From adef5c738a98074523fbf4739846ed73305a9976 Mon Sep 17 00:00:00 2001 From: "michaelp%netscape.com" Date: Tue, 15 Sep 1998 03:48:58 +0000 Subject: [PATCH] new plugin world. git-svn-id: svn://10.0.0.236/trunk@10036 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/modules/plugin/base/src/Makefile | 3 +- mozilla/modules/plugin/base/src/makefile.win | 3 +- .../modules/plugin/base/src/ns4xPlugin.cpp | 63 +-- mozilla/modules/plugin/base/src/ns4xPlugin.h | 22 +- .../plugin/base/src/ns4xPluginInstance.cpp | 55 ++- .../plugin/base/src/ns4xPluginInstance.h | 15 + .../plugin/base/src/ns4xPluginStream.cpp | 16 +- .../modules/plugin/base/src/nsIPluginHost.h | 18 +- .../plugin/base/src/nsIPluginInstanceOwner.h | 101 +++++ .../plugin/base/src/nsPluginHostImpl.cpp | 426 +++++++++++++----- .../plugin/base/src/nsPluginHostImpl.h | 31 +- .../plugin/base/src/nsPluginInstancePeer.cpp | 92 +++- .../plugin/base/src/nsPluginInstancePeer.h | 16 +- .../plugin/base/src/nsPluginStreamPeer.cpp | 11 +- .../plugin/base/src/nsPluginStreamPeer.h | 15 +- mozilla/modules/plugin/nglsrc/Makefile | 3 +- mozilla/modules/plugin/nglsrc/makefile.win | 3 +- mozilla/modules/plugin/nglsrc/ns4xPlugin.cpp | 63 +-- mozilla/modules/plugin/nglsrc/ns4xPlugin.h | 22 +- .../plugin/nglsrc/ns4xPluginInstance.cpp | 55 ++- .../plugin/nglsrc/ns4xPluginInstance.h | 15 + .../plugin/nglsrc/ns4xPluginStream.cpp | 16 +- mozilla/modules/plugin/nglsrc/nsIPluginHost.h | 18 +- .../plugin/nglsrc/nsIPluginInstanceOwner.h | 101 +++++ .../plugin/nglsrc/nsPluginHostImpl.cpp | 426 +++++++++++++----- .../modules/plugin/nglsrc/nsPluginHostImpl.h | 31 +- .../plugin/nglsrc/nsPluginInstancePeer.cpp | 92 +++- .../plugin/nglsrc/nsPluginInstancePeer.h | 16 +- .../plugin/nglsrc/nsPluginStreamPeer.cpp | 11 +- .../plugin/nglsrc/nsPluginStreamPeer.h | 15 +- 30 files changed, 1382 insertions(+), 392 deletions(-) create mode 100644 mozilla/modules/plugin/base/src/nsIPluginInstanceOwner.h create mode 100644 mozilla/modules/plugin/nglsrc/nsIPluginInstanceOwner.h diff --git a/mozilla/modules/plugin/base/src/Makefile b/mozilla/modules/plugin/base/src/Makefile index cbd0c98efbc..e1caf6261ba 100644 --- a/mozilla/modules/plugin/base/src/Makefile +++ b/mozilla/modules/plugin/base/src/Makefile @@ -25,7 +25,8 @@ LIBRARY_NAME=raptorplugin EXPORTS = \ nsPluginsCID.h \ - nsIPluginHost.h + nsIPluginHost.h \ + nsIPluginInstanceOwner.h CPPSRCS = \ nsPluginHostImpl.cpp \ diff --git a/mozilla/modules/plugin/base/src/makefile.win b/mozilla/modules/plugin/base/src/makefile.win index 34a032a2777..3677b37368a 100644 --- a/mozilla/modules/plugin/base/src/makefile.win +++ b/mozilla/modules/plugin/base/src/makefile.win @@ -20,7 +20,8 @@ IGNORE_MANIFEST=1 EXPORTS = \ nsPluginsCID.h \ - nsIPluginHost.h + nsIPluginHost.h \ + nsIPluginInstanceOwner.h MAKE_OBJ_TYPE = DLL DLLNAME = raptorplugin diff --git a/mozilla/modules/plugin/base/src/ns4xPlugin.cpp b/mozilla/modules/plugin/base/src/ns4xPlugin.cpp index aa5b3fd09bd..12304120272 100644 --- a/mozilla/modules/plugin/base/src/ns4xPlugin.cpp +++ b/mozilla/modules/plugin/base/src/ns4xPlugin.cpp @@ -24,20 +24,6 @@ #include "nsIPluginStream.h" #include "ns4xPluginInstance.h" -//////////////////////////////////////////////////////////////////////// - -#ifdef XP_WIN -// XXX These are defined in platform specific FE directories right now :-/ -typedef NPError (__stdcall *NP_GETENTRYPOINTS)(NPPluginFuncs* pCallbacks); -typedef NPError (__stdcall *NP_PLUGININIT)(const NPNetscapeFuncs* pCallbacks); -typedef NPError (__stdcall *NP_PLUGINSHUTDOWN)(); -#else -typedef NPError (*NP_GETENTRYPOINTS)(NPPluginFuncs* pCallbacks); -typedef NPError (*NP_PLUGININIT)(const NPNetscapeFuncs* pCallbacks); -typedef NPError (*NP_PLUGINSHUTDOWN)(); -#endif /* XP_WIN */ - - //////////////////////////////////////////////////////////////////////// NPNetscapeFuncs ns4xPlugin::CALLBACKS; @@ -90,18 +76,17 @@ ns4xPlugin::CheckClassInitialized(void) //////////////////////////////////////////////////////////////////////// -ns4xPlugin::ns4xPlugin(NPPluginFuncs* callbacks) +ns4xPlugin::ns4xPlugin(NPPluginFuncs* callbacks, NP_PLUGINSHUTDOWN aShutdown) { NS_INIT_REFCNT(); + memcpy((void*) &fCallbacks, (void*) callbacks, sizeof(fCallbacks)); + fShutdownEntry = aShutdown; } ns4xPlugin::~ns4xPlugin(void) { - NS_IF_RELEASE(mPluginManager); - NS_IF_RELEASE(mNetworkManager); - NS_IF_RELEASE(mMalloc); } @@ -182,6 +167,9 @@ ns4xPlugin::CreatePlugin(PRLibrary *library, return NS_ERROR_FAILURE; #endif + NP_PLUGINSHUTDOWN pfnShutdown = + (NP_PLUGINSHUTDOWN)PR_FindSymbol(library, "NP_Shutdown"); + // the NP_Initialize entry point was misnamed as NP_PluginInit, // early in plugin project development. Its correct name is // documented now, and new developers expect it to work. However, @@ -201,9 +189,11 @@ ns4xPlugin::CreatePlugin(PRLibrary *library, if (pfnInitialize(&ns4xPlugin::CALLBACKS) != NS_OK) return NS_ERROR_UNEXPECTED; // XXX shoudl convert the 4.x error... - (*result) = new ns4xPlugin(&callbacks); + *result = new ns4xPlugin(&callbacks, pfnShutdown); - if ((*result) == NULL) + NS_ADDREF(*result); + + if (*result == NULL) return NS_ERROR_OUT_OF_MEMORY; return NS_OK; @@ -268,6 +258,15 @@ ns4xPlugin::Initialize(nsISupports* browserInterfaces) nsresult ns4xPlugin::Shutdown(void) { + if (nsnull != fShutdownEntry) + { +#ifdef NS_DEBUG +printf("shutting down plugin %08x\n", this); +#endif + fShutdownEntry(); + fShutdownEntry = nsnull; + } + NS_IF_RELEASE(mPluginManager); NS_IF_RELEASE(mNetworkManager); NS_IF_RELEASE(mMalloc); @@ -278,6 +277,7 @@ ns4xPlugin::Shutdown(void) nsresult ns4xPlugin::GetMIMEDescription(const char* *resultingDesc) { +printf("plugin getmimedescription called\n"); *resultingDesc = ""; return NS_OK; // XXX make a callback, etc. } @@ -285,12 +285,7 @@ ns4xPlugin::GetMIMEDescription(const char* *resultingDesc) nsresult ns4xPlugin::GetValue(nsPluginVariable variable, void *value) { - return NS_OK; -} - -nsresult -ns4xPlugin::SetValue(nsPluginVariable variable, void *value) -{ +printf("plugin getvalue %d called\n", variable); return NS_OK; } @@ -645,13 +640,26 @@ ns4xPlugin::_getvalue(NPP npp, NPNVariable variable, void *result) nsresult NP_EXPORT ns4xPlugin::_setvalue(NPP npp, NPPVariable variable, void *result) { - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + ns4xPluginInstance *inst = (ns4xPluginInstance *) npp->ndata; NS_ASSERTION(inst != NULL, "null instance"); if (inst == NULL) return NS_ERROR_FAILURE; // XXX + switch (variable) + { + case NPPVpluginWindowBool: + return inst->SetWindowless(*((NPBool *)result)); + + case NPPVpluginTransparentBool: + return inst->SetTransparent(*((NPBool *)result)); + + default: + return NS_OK; + } + +#if 0 nsIPluginInstancePeer *peer; if (NS_OK == inst->GetPeer(&peer)) @@ -666,6 +674,7 @@ ns4xPlugin::_setvalue(NPP npp, NPPVariable variable, void *result) } else return NS_ERROR_UNEXPECTED; +#endif } nsresult NP_EXPORT diff --git a/mozilla/modules/plugin/base/src/ns4xPlugin.h b/mozilla/modules/plugin/base/src/ns4xPlugin.h index e7b958d4721..69355e8e98a 100644 --- a/mozilla/modules/plugin/base/src/ns4xPlugin.h +++ b/mozilla/modules/plugin/base/src/ns4xPlugin.h @@ -43,13 +43,28 @@ //////////////////////////////////////////////////////////////////////// +// XXX These are defined in platform specific FE directories right now :-/ + +//BTW: this sucks rocks. +#ifdef XP_WIN +#define PLUGIN_ENTRYPOINT_CALL_TYPE __stdcall +#else +#define PLUGIN_ENTRYPOINT_CALL_TYPE +#endif + +typedef NPError (PLUGIN_ENTRYPOINT_CALL_TYPE *NP_GETENTRYPOINTS)(NPPluginFuncs* pCallbacks); +typedef NPError (PLUGIN_ENTRYPOINT_CALL_TYPE *NP_PLUGININIT)(const NPNetscapeFuncs* pCallbacks); +typedef NPError (PLUGIN_ENTRYPOINT_CALL_TYPE *NP_PLUGINSHUTDOWN)(); + +//////////////////////////////////////////////////////////////////////// + /** * A 5.0 wrapper for a 4.x style plugin. */ class ns4xPlugin : public nsILiveConnectPlugin { public: - ns4xPlugin(NPPluginFuncs* callbacks); + ns4xPlugin(NPPluginFuncs* callbacks, NP_PLUGINSHUTDOWN aShutdown); ~ns4xPlugin(void); NS_DECL_ISUPPORTS @@ -76,9 +91,6 @@ public: NS_IMETHOD GetValue(nsPluginVariable variable, void *value); - NS_IMETHOD - SetValue(nsPluginVariable variable, void *value); - //nsILiveConnectPlugin interface NS_IMETHOD @@ -207,6 +219,8 @@ protected: */ NPPluginFuncs fCallbacks; + NP_PLUGINSHUTDOWN fShutdownEntry; + /** * The browser-side callbacks that a 4.x-style plugin calls. */ diff --git a/mozilla/modules/plugin/base/src/ns4xPluginInstance.cpp b/mozilla/modules/plugin/base/src/ns4xPluginInstance.cpp index d01e5bfe0d9..6674ce3bb18 100644 --- a/mozilla/modules/plugin/base/src/ns4xPluginInstance.cpp +++ b/mozilla/modules/plugin/base/src/ns4xPluginInstance.cpp @@ -36,6 +36,9 @@ ns4xPluginInstance :: ns4xPluginInstance(NPPluginFuncs* callbacks) fNPP.ndata = this; fPeer = nsnull; + + mWindowless = PR_FALSE; + mTransparent = PR_FALSE; } @@ -140,6 +143,7 @@ NS_IMETHODIMP ns4xPluginInstance :: GetPeer(nsIPluginInstancePeer* *resultingPee { NS_ADDREF(fPeer); *resultingPeer = fPeer; + return NS_OK; } @@ -148,17 +152,30 @@ NS_IMETHODIMP ns4xPluginInstance::Start(void) // XXX At some point, we maybe should implement start and stop to // load/unload the 4.x plugin, just in case there are some plugins // that rely on that behavior... +printf("instance start called\n"); return NS_OK; } NS_IMETHODIMP ns4xPluginInstance::Stop(void) { +printf("instance stop called\n"); return NS_OK; } NS_IMETHODIMP ns4xPluginInstance::Destroy(void) { - return NS_OK; + nsresult error; + +printf("instance destroy called\n"); + if (fCallbacks->destroy == NULL) + return NS_ERROR_FAILURE; // XXX right error? + + NPSavedData *sdata; + + error = (nsresult)CallNPP_DestroyProc(fCallbacks->destroy, + &fNPP, &sdata); // saved data + + return error; } NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window) @@ -217,11 +234,13 @@ NS_IMETHODIMP ns4xPluginInstance::NewStream(nsIPluginStreamPeer* peer, nsIPlugin NS_IMETHODIMP ns4xPluginInstance::Print(nsPluginPrint* platformPrint) { +printf("instance print called\n"); return NS_OK; } NS_IMETHODIMP ns4xPluginInstance::HandleEvent(nsPluginEvent* event, PRBool* handled) { +printf("instance handleevent called\n"); *handled = PR_FALSE; return NS_OK; @@ -241,3 +260,37 @@ NS_IMETHODIMP ns4xPluginInstance::URLNotify(const char* url, const char* target, return NS_OK; //XXX this seems bad... } + +NS_IMETHODIMP ns4xPluginInstance :: GetValue(nsPluginInstanceVariable variable, void *value) +{ + nsresult rv = NS_OK; + + switch (variable) + { + case nsPluginInstanceVariable_WindowlessBool: + *(PRBool *)value = mWindowless; + break; + + case nsPluginInstanceVariable_TransparentBool: + *(PRBool *)value = mTransparent; + break; + + default: + rv = NS_ERROR_FAILURE; //XXX this is bad + } + + return rv; +} + +NS_IMETHODIMP ns4xPluginInstance :: SetWindowless(PRBool aWindowless) +{ + mWindowless = aWindowless; + return NS_OK; +} + +NS_IMETHODIMP ns4xPluginInstance :: SetTransparent(PRBool aTransparent) +{ + mTransparent = aTransparent; + return NS_OK; +} + diff --git a/mozilla/modules/plugin/base/src/ns4xPluginInstance.h b/mozilla/modules/plugin/base/src/ns4xPluginInstance.h index d9935010816..4c0a8270534 100644 --- a/mozilla/modules/plugin/base/src/ns4xPluginInstance.h +++ b/mozilla/modules/plugin/base/src/ns4xPluginInstance.h @@ -83,6 +83,9 @@ public: URLNotify(const char* url, const char* target, nsPluginReason reason, void* notifyData); + NS_IMETHOD + GetValue(nsPluginInstanceVariable variable, void *value); + //////////////////////////////////////////////////////////////////////// // ns4xPluginInstance-specific methods @@ -105,6 +108,12 @@ public: return NS_OK; }; + NS_IMETHOD + SetWindowless(PRBool aWindowless); + + NS_IMETHOD + SetTransparent(PRBool aTransparent); + protected: /** @@ -124,6 +133,12 @@ protected: * instance and the browser. */ NPP_t fNPP; + + //these are used to store the windowless properties + //which the browser will later query + + PRBool mWindowless; + PRBool mTransparent; }; diff --git a/mozilla/modules/plugin/base/src/ns4xPluginStream.cpp b/mozilla/modules/plugin/base/src/ns4xPluginStream.cpp index 5a1c52a9fcb..e60c894d753 100644 --- a/mozilla/modules/plugin/base/src/ns4xPluginStream.cpp +++ b/mozilla/modules/plugin/base/src/ns4xPluginStream.cpp @@ -28,6 +28,9 @@ ns4xPluginStream::ns4xPluginStream(void) { NS_INIT_REFCNT(); + fPeer = nsnull; + fInstance = nsnull; + // Initialize the 4.x interface structure memset(&fNPStream, 0, sizeof(fNPStream)); } @@ -98,7 +101,7 @@ NS_IMETHODIMP ns4xPluginStream::Initialize(ns4xPluginInstance* instance, NS_ASSERTION(fInstance != NULL, "null instance"); - fInstance->AddRef(); + NS_ADDREF(fInstance); NS_ASSERTION(fPeer != NULL, "null peer"); @@ -225,7 +228,6 @@ NS_IMETHODIMP ns4xPluginStream :: Close(void) { const NPPluginFuncs *callbacks; NPP npp; - nsresult rv; void *notifydata; fInstance->GetCallbacks(&callbacks); @@ -253,15 +255,7 @@ NS_IMETHODIMP ns4xPluginStream :: Close(void) notifydata); } - if (callbacks->destroystream == NULL) - return NS_OK; - - rv = (nsresult)CallNPP_DestroyStreamProc(callbacks->destroystream, - npp, - &fNPStream, - (NPReason)reason); - - return rv; + return NS_OK; } //////////////////////////////////////////////////////////////////////// diff --git a/mozilla/modules/plugin/base/src/nsIPluginHost.h b/mozilla/modules/plugin/base/src/nsIPluginHost.h index 690a24fca50..f169f620fa3 100644 --- a/mozilla/modules/plugin/base/src/nsIPluginHost.h +++ b/mozilla/modules/plugin/base/src/nsIPluginHost.h @@ -23,6 +23,8 @@ #include "nsplugindefs.h" #include "nsIFactory.h" #include "nsString.h" +#include "nsIPluginInstanceOwner.h" +#include "nsIStreamListener.h" class nsIURL; @@ -37,21 +39,29 @@ public: NS_IMETHOD Init(void) = 0; + NS_IMETHOD + Destroy(void) = 0; + NS_IMETHOD LoadPlugins(void) = 0; NS_IMETHOD - InstantiatePlugin(const char *aMimeType, nsIURL *aURL, nsIPluginInstance ** aPluginInst) = 0; + InstantiatePlugin(const char *aMimeType, nsIURL *aURL, nsIPluginInstanceOwner *aOwner) = 0; NS_IMETHOD - InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst, - nsPluginWindow *aWindow, nsString& aURL) = 0; + InstantiatePlugin(const char *aMimeType, nsString& aURLSpec, nsIPluginInstanceOwner *aOwner) = 0; + + NS_IMETHOD + InstantiatePlugin(const char *aMimeType, nsString& aURLSpec, nsIStreamListener *&aStreamListener, nsIPluginInstanceOwner *aOwner) = 0; NS_IMETHOD NewPluginStream(const nsString& aURL, nsIPluginInstance *aInstance, void *aNotifyData) = 0; NS_IMETHOD - NewPluginStream(const nsString& aURL, nsIPluginInstance **aInstance, nsPluginWindow *aWindow) = 0; + NewPluginStream(const nsString& aURL, nsIPluginInstanceOwner *aOwner, void *aNotifyData) = 0; + + NS_IMETHOD + NewPluginStream(nsIStreamListener *&aStreamListener, nsIPluginInstance *aInstance, void *aNotifyData) = 0; }; #endif diff --git a/mozilla/modules/plugin/base/src/nsIPluginInstanceOwner.h b/mozilla/modules/plugin/base/src/nsIPluginInstanceOwner.h new file mode 100644 index 00000000000..db85eb3c292 --- /dev/null +++ b/mozilla/modules/plugin/base/src/nsIPluginInstanceOwner.h @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsIPluginInstanceOwner_h___ +#define nsIPluginInstanceOwner_h___ + +#include "nsISupports.h" +#include "nsplugin.h" + +#define NS_IPLUGININSTANCEOWNER_IID \ +{ 0x18270870, 0x32f1, 0x11d2, \ +{ 0xa8, 0x30, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } } + +struct nsIPluginInstanceOwner : public nsISupports +{ +public: + + /** + * Let the owner know that an instance has been created + * + */ + NS_IMETHOD + SetInstance(nsIPluginInstance *aInstance) = 0; + + /** + * Get the instance associated with this owner. + * + */ + NS_IMETHOD + GetInstance(nsIPluginInstance *&aInstance) = 0; + + /** + * Get a handle to the window structure of the owner. + * This pointer cannot be made persistant by the caller. + * + */ + NS_IMETHOD + GetWindow(nsPluginWindow *&aWindow) = 0; + + /** + * Get the display mode for the plugin instance. + */ + NS_IMETHOD + GetMode(nsPluginMode *aMode) = 0; + + /** + * Get a ptr to the paired list of attribute names and values, + * returns the length of the array. + * + * Each name or value is a null-terminated string. + */ + NS_IMETHOD + GetAttributes(PRUint16& n, const char*const*& names, const char*const*& values) = 0; + + /** + * Gets the value for the named attribute. + * + * @param name - the name of the attribute to find + * @param result - the resulting attribute + * @result - NS_OK if this operation was successful, NS_ERROR_FAILURE if + * this operation failed. result is set to NULL if the attribute is not found + * else to the found value. + */ + NS_IMETHOD + GetAttribute(const char* name, const char* *result) = 0; + + /** + * Create a place for the plugin to live in the owner's + * environment. this may or may not create a window + * depending on the windowless state of the plugin instance. + * + */ + NS_IMETHOD + CreateWidget(void) = 0; + + /** + * Called when there is a valid target so that the proper + * frame can be updated with new content. will not be called + * with nsnull aTarget. + * + */ + NS_IMETHOD + GetURL(const char *aURL, const char *aTarget, void *aPostData) = 0; +}; + +#endif diff --git a/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp b/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp index c499a1e3542..2258733c19a 100644 --- a/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp +++ b/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp @@ -27,9 +27,12 @@ #include "nsIStreamListener.h" #include "nsIURL.h" #include "nsIInputStream.h" +#include "prprf.h" +#include "gui.h" #ifdef XP_PC #include "windows.h" +#include "winbase.h" #endif static NS_DEFINE_IID(kIPluginInstanceIID, NS_IPLUGININSTANCE_IID); @@ -63,6 +66,8 @@ nsPluginTag :: nsPluginTag() nsPluginTag :: ~nsPluginTag() { + NS_IF_RELEASE(mEntryPoint); + if (nsnull != mName) { PR_Free(mName); @@ -116,8 +121,6 @@ nsPluginTag :: ~nsPluginTag() PR_UnloadLibrary(mLibrary); mLibrary = nsnull; } - - mEntryPoint = nsnull; } class nsPluginStreamListener : public nsIStreamListener @@ -148,39 +151,40 @@ public: //locals nsresult Initialize(nsIURL *aURL, nsIPluginInstance *aInstance, void *aNotifyData); - nsresult Initialize(nsIURL *aURL, nsIPluginInstance **aInstance, - nsPluginWindow *aWindow, nsIPluginHost *aHost); + nsresult Initialize(nsIURL *aURL, nsIPluginInstanceOwner *aOwner, + nsIPluginHost *aHost, void *aNotifyData); + nsresult Initialize(nsIPluginInstance *aInstance, void *aNotifyData); private: - nsIURL *mURL; - nsPluginStreamPeer *mPeer; - nsIPluginInstance *mInstance; - nsIPluginInstance **mFarInstance; - PRBool mBound; - nsIPluginStream *mStream; - char *mMIMEType; - PRUint8 *mBuffer; - PRUint32 mBufSize; - void *mNotifyData; - nsPluginWindow *mWindow; - nsIPluginHost *mHost; - PRInt32 mLength; - PRBool mGotProgress; + nsIURL *mURL; + nsPluginStreamPeer *mPeer; + nsIPluginInstanceOwner *mOwner; + nsIPluginInstance *mInstance; + PRBool mBound; + nsIPluginStream *mStream; + char *mMIMEType; + PRUint8 *mBuffer; + PRUint32 mBufSize; + void *mNotifyData; + nsIPluginHost *mHost; + PRInt32 mLength; + PRBool mGotProgress; }; nsPluginStreamListener :: nsPluginStreamListener() { + NS_INIT_REFCNT(); + mURL = nsnull; mPeer = nsnull; + mOwner = nsnull; mInstance = nsnull; - mFarInstance = nsnull; mBound = PR_FALSE; mStream = nsnull; mMIMEType = nsnull; mBuffer = nsnull; mBufSize = 0; mNotifyData = nsnull; - mWindow = nsnull; mHost = nsnull; mLength = 0; mGotProgress = PR_FALSE; @@ -188,10 +192,14 @@ nsPluginStreamListener :: nsPluginStreamListener() nsPluginStreamListener :: ~nsPluginStreamListener() { +#ifdef NS_DEBUG +printf("killing stream for %s\n", mURL ? mURL->GetSpec() : "(unknown URL)"); +#endif NS_IF_RELEASE(mURL); - NS_IF_RELEASE(mPeer); + NS_IF_RELEASE(mOwner); NS_IF_RELEASE(mInstance); NS_IF_RELEASE(mStream); + NS_IF_RELEASE(mPeer); if (nsnull != mMIMEType) { @@ -206,8 +214,6 @@ nsPluginStreamListener :: ~nsPluginStreamListener() } mNotifyData = nsnull; - mWindow = nsnull; - mFarInstance = nsnull; NS_IF_RELEASE(mHost); } @@ -249,6 +255,9 @@ nsresult nsPluginStreamListener :: QueryInterface(const nsIID& aIID, nsresult nsPluginStreamListener :: Initialize(nsIURL *aURL, nsIPluginInstance *aInstance, void *aNotifyData) { +#ifdef NS_DEBUG +printf("created stream for %s\n", aURL->GetSpec()); +#endif mURL = aURL; NS_ADDREF(mURL); @@ -260,15 +269,17 @@ nsresult nsPluginStreamListener :: Initialize(nsIURL *aURL, nsIPluginInstance *a return NS_OK; } -nsresult nsPluginStreamListener :: Initialize(nsIURL *aURL, nsIPluginInstance **aInstance, - nsPluginWindow *aWindow, nsIPluginHost *aHost) +nsresult nsPluginStreamListener :: Initialize(nsIURL *aURL, nsIPluginInstanceOwner *aOwner, + nsIPluginHost *aHost, void *aNotifyData) { +#ifdef NS_DEBUG +printf("created stream for %s\n", aURL->GetSpec()); +#endif mURL = aURL; NS_ADDREF(mURL); - mFarInstance = aInstance; - - mWindow = aWindow; + mOwner = aOwner; + NS_ADDREF(mOwner); mHost = aHost; NS_IF_ADDREF(mHost); @@ -276,6 +287,19 @@ nsresult nsPluginStreamListener :: Initialize(nsIURL *aURL, nsIPluginInstance ** return NS_OK; } +nsresult nsPluginStreamListener :: Initialize(nsIPluginInstance *aInstance, void *aNotifyData) +{ +#ifdef NS_DEBUG +printf("created stream for (unknown URL)\n"); +#endif + mInstance = aInstance; + NS_ADDREF(mInstance); + + mNotifyData = aNotifyData; + + return NS_OK; +} + NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char *aContentType) { nsresult rv = NS_OK; @@ -286,7 +310,7 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char mMIMEType = (char *)PR_Malloc(len + 1); if (nsnull != mMIMEType) - strcpy(mMIMEType, aContentType); + PL_strcpy(mMIMEType, aContentType); else rv = NS_ERROR_OUT_OF_MEMORY; } @@ -294,23 +318,39 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char //now that we have the mime type, see if we need //to load a plugin... - if ((nsnull == mInstance) && (nsnull != mFarInstance) && - (nsnull != mHost) && (nsnull != mWindow)) + nsIPluginInstance *instance = nsnull; + nsPluginWindow *window = nsnull; + + if ((nsnull == mInstance) && (nsnull != mOwner)) { - rv = mHost->InstantiatePlugin(aContentType, aURL, mFarInstance); + mOwner->GetInstance(instance); + mOwner->GetWindow(window); - if (NS_OK == rv) + if ((nsnull == instance) && (nsnull != mHost) && (nsnull != window)) { - mInstance = *mFarInstance; - NS_ADDREF(mInstance); + rv = mHost->InstantiatePlugin(aContentType, aURL, mOwner); - (*mFarInstance)->Start(); - (*mFarInstance)->SetWindow(mWindow); + if (NS_OK == rv) + { + mOwner->GetInstance(instance); + + if (nsnull != instance) + { + instance->Start(); + mOwner->CreateWidget(); + instance->SetWindow(window); + } + } } } + else + { + instance = mInstance; + NS_ADDREF(instance); + } if ((PR_TRUE == mGotProgress) && (nsnull == mPeer) && - (nsnull != mInstance) && (PR_FALSE == mBound)) + (nsnull != instance) && (PR_FALSE == mBound)) { //need to create new peer and and tell plugin that we have new stream... @@ -319,9 +359,11 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char NS_ADDREF(mPeer); mPeer->Initialize(aURL, mLength, 0, aContentType, mNotifyData); - mInstance->NewStream(mPeer, &mStream); + instance->NewStream(mPeer, &mStream); } + NS_IF_RELEASE(instance); + mBound = PR_TRUE; return rv; @@ -329,16 +371,31 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char NS_IMETHODIMP nsPluginStreamListener :: OnProgress(nsIURL* aURL, PRInt32 aProgress, PRInt32 aProgressMax) { - if ((aProgress == 0) && (nsnull == mPeer) && (nsnull != mInstance)) + if ((aProgress == 0) && (nsnull == mPeer)) { - //need to create new peer and and tell plugin that we have new stream... + nsIPluginInstance *instance = nsnull; - mPeer = (nsPluginStreamPeer *)new nsPluginStreamPeer(); + if (nsnull == mInstance) + mOwner->GetInstance(instance); + else + { + instance = mInstance; + NS_ADDREF(instance); + } - NS_ADDREF(mPeer); + if (nsnull != instance) + { + //need to create new peer and and tell plugin that we have new stream... - mPeer->Initialize(aURL, aProgressMax, 0, mMIMEType, mNotifyData); - mInstance->NewStream(mPeer, &mStream); + mPeer = (nsPluginStreamPeer *)new nsPluginStreamPeer(); + + NS_ADDREF(mPeer); + + mPeer->Initialize(aURL, aProgressMax, 0, mMIMEType, mNotifyData); + instance->NewStream(mPeer, &mStream); + + NS_RELEASE(instance); + } } mLength = aProgressMax; @@ -354,10 +411,26 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStatus(nsIURL* aURL, const nsString &a NS_IMETHODIMP nsPluginStreamListener :: OnStopBinding(nsIURL* aURL, PRInt32 aStatus, const nsString &aMsg) { + nsresult rv; + + //XXX this is incomplete... MMP + + if (nsnull != mPeer) + { + if (aStatus == NS_BINDING_SUCCEEDED) + mPeer->SetReason(nsPluginReason_Done); + else + mPeer->SetReason(nsPluginReason_UserBreak); + + rv = NS_OK; + } + else + rv = NS_ERROR_UNEXPECTED; + if (nsnull != mStream) mStream->Close(); - return NS_OK; + return rv; } NS_IMETHODIMP nsPluginStreamListener :: GetBindInfo(nsIURL* aURL) @@ -389,10 +462,14 @@ NS_IMETHODIMP nsPluginStreamListener :: OnDataAvailable(nsIURL* aURL, nsIInputSt nsPluginHostImpl :: nsPluginHostImpl() { + NS_INIT_REFCNT(); } nsPluginHostImpl :: ~nsPluginHostImpl() { +#ifdef NS_DEBUG +printf("killing plugin host\n"); +#endif if (nsnull != mPluginPath) { PR_Free(mPluginPath); @@ -465,6 +542,12 @@ nsresult nsPluginHostImpl :: QueryInterface(const nsIID& aIID, return NS_NOINTERFACE; } +NS_IMETHODIMP nsPluginHostImpl :: GetValue(nsPluginManagerVariable variable, void *value) +{ +printf("manager getvalue %d called\n", variable); + return NS_OK; +} + nsresult nsPluginHostImpl :: ReloadPlugins(PRBool reloadPages) { return LoadPlugins(); @@ -473,41 +556,61 @@ nsresult nsPluginHostImpl :: ReloadPlugins(PRBool reloadPages) //XXX need to find out score on this one... MMP nsresult nsPluginHostImpl :: UserAgent(const char **retstring) { - *retstring = "NGLayout"; + *retstring = (const char *)"Mozilla/4.05 [en] (Windows;I)"; return NS_OK; } -nsresult nsPluginHostImpl :: GetValue(nsPluginManagerVariable variable, void *value) -{ - return NS_OK; -} - -nsresult nsPluginHostImpl :: SetValue(nsPluginManagerVariable variable, void *value) -{ - return NS_OK; -} - -NS_IMETHODIMP nsPluginHostImpl :: GetURL(nsISupports* peer, const char* url, +NS_IMETHODIMP nsPluginHostImpl :: GetURL(nsISupports* inst, const char* url, const char* target, void* notifyData, const char* altHost, const char* referrer, PRBool forceJSEnabled) { - nsAutoString string = nsAutoString(url); - nsIPluginInstance *inst; - nsresult rv; + nsAutoString string = nsAutoString(url); + nsIPluginInstance *instance; + nsresult rv; - rv = peer->QueryInterface(kIPluginInstanceIID, (void **)&inst); + rv = inst->QueryInterface(kIPluginInstanceIID, (void **)&instance); if (NS_OK == rv) { - NewPluginStream(string, inst, notifyData); - NS_RELEASE(inst); + if (nsnull != target) + { + nsPluginInstancePeerImpl *peer; + + rv = instance->GetPeer((nsIPluginInstancePeer **)&peer); + + if (NS_OK == rv) + { + nsIPluginInstanceOwner *owner; + + rv = peer->GetOwner(owner); + + if (NS_OK == rv) + { + if ((0 == PL_strcmp(target, "newwindow")) || + (0 == PL_strcmp(target, "_new"))) + target = "_blank"; + else if (0 == PL_strcmp(target, "_current")) + target = "_self"; + + rv = owner->GetURL(url, target, nsnull); + NS_RELEASE(owner); + } + + NS_RELEASE(peer); + } + } + + if ((nsnull != notifyData) || (nsnull == target)) + rv = NewPluginStream(string, instance, notifyData); + + NS_RELEASE(instance); } return rv; } -NS_IMETHODIMP nsPluginHostImpl :: PostURL(nsISupports* peer, +NS_IMETHODIMP nsPluginHostImpl :: PostURL(nsISupports* inst, const char* url, const char* target, PRUint32 postDataLen, const char* postData, PRBool isFile, void* notifyData, @@ -515,20 +618,22 @@ NS_IMETHODIMP nsPluginHostImpl :: PostURL(nsISupports* peer, PRBool forceJSEnabled, PRUint32 postHeadersLength, const char* postHeaders) { +printf("network manager posturl called\n"); return NS_ERROR_NOT_IMPLEMENTED; } -NS_IMETHODIMP -nsPluginHostImpl::FindProxyForURL(const char* url, char* *result) +NS_IMETHODIMP nsPluginHostImpl :: FindProxyForURL(const char* url, char* *result) { +printf("network manager findproxyforurl called\n"); return NS_ERROR_NOT_IMPLEMENTED; } nsresult nsPluginHostImpl :: Init(void) { - nsresult rv; + nsresult rv; nsISupports *object; +// rv = nsMalloc::Create(nsnull, kIMallocIID, (void **)&mMalloc); rv = nsMalloc::Create(nsnull, kIMallocIID, (void **)&object); if (NS_OK == rv) @@ -540,6 +645,21 @@ nsresult nsPluginHostImpl :: Init(void) return rv; } +nsresult nsPluginHostImpl :: Destroy(void) +{ + nsPluginTag *plug = mPlugins; + + while (nsnull != plug) + { + if (nsnull != plug->mEntryPoint) + plug->mEntryPoint->Shutdown(); + + plug = plug->mNext; + } + + return NS_OK; +} + nsresult nsPluginHostImpl :: LoadPlugins(void) { #ifdef XP_PC @@ -610,7 +730,7 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) if (nsnull != mPluginPath) { - strcpy(mPluginPath, path); + PL_strcpy(mPluginPath, path); mPluginPath[pathlen] = '\\'; mPluginPath[pathlen + 1] = 0; @@ -625,7 +745,7 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) while (dent = PR_ReadDir(dir, PR_SKIP_BOTH)) { - PRInt32 len = strlen(dent->name); + PRInt32 len = PL_strlen(dent->name); if (len > 6) //np*.dll { @@ -634,8 +754,8 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) { PRLibrary *plugin; - strcpy(path, mPluginPath); - strcat(path, dent->name); + PL_strcpy(path, mPluginPath); + PL_strcat(path, dent->name); plugin = PR_LoadLibrary(path); @@ -673,7 +793,7 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) if (nsnull == plugintag->mName) break; else - strcpy(plugintag->mName, dent->name); + PL_strcpy(plugintag->mName, dent->name); ::VerQueryValue(verbuf, TEXT("\\StringFileInfo\\040904E4\\FileDescription"), @@ -688,7 +808,7 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) if (nsnull == plugintag->mDescription) break; else - strcpy(plugintag->mDescription, buf); + PL_strcpy(plugintag->mDescription, buf); } ::VerQueryValue(verbuf, @@ -704,7 +824,7 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) if (nsnull == plugintag->mMimeType) break; else - strcpy(plugintag->mMimeType, buf); + PL_strcpy(plugintag->mMimeType, buf); buf = plugintag->mMimeType; @@ -758,7 +878,7 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) if (nsnull == plugintag->mMimeDescription) break; else - strcpy(plugintag->mMimeDescription, buf); + PL_strcpy(plugintag->mMimeDescription, buf); buf = plugintag->mMimeDescription; @@ -813,7 +933,7 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) if (nsnull == plugintag->mExtensions) break; else - strcpy(plugintag->mExtensions, buf); + PL_strcpy(plugintag->mExtensions, buf); buf = plugintag->mExtensions; @@ -897,7 +1017,7 @@ printf("plugin %s added to list %s\n", plugintag->mName, (plugintag->mFlags & NS } nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsIURL *aURL, - nsIPluginInstance ** aPluginInst) + nsIPluginInstanceOwner *aOwner) { nsPluginTag *plugins = nsnull; PRInt32 variants, cnt; @@ -1001,8 +1121,8 @@ printf("found plugin via extension %s\n", ext); { char path[2000]; - strcpy(path, mPluginPath); - strcat(path, plugins->mName); + PL_strcpy(path, mPluginPath); + PL_strcat(path, plugins->mName); plugins->mLibrary = PR_LoadLibrary(path); #ifdef NS_DEBUG @@ -1032,17 +1152,23 @@ printf("result of creating plugin adapter: %d\n", rv); if (nsnull != plugins->mEntryPoint) { + nsIPluginInstance *instance; + //create an instance - if (NS_OK == plugins->mEntryPoint->CreateInstance(nsnull, kIPluginInstanceIID, (void **)aPluginInst)) + if (NS_OK == plugins->mEntryPoint->CreateInstance(nsnull, kIPluginInstanceIID, (void **)&instance)) { #ifdef NS_DEBUG -printf("successfully created plugin instance\n"); +printf("successfully created plugin instance %08x for %s, mimetype %s\n", instance, plugins->mName, aMimeType ? aMimeType : "(none)"); #endif + aOwner->SetInstance(instance); + nsPluginInstancePeerImpl *peer = new nsPluginInstancePeerImpl(); - peer->Initialize(*aPluginInst); //this will not add a ref to the instance. MMP - (*aPluginInst)->Initialize(peer); + peer->Initialize(aOwner, aMimeType); //this will not add a ref to the instance (or owner). MMP + instance->Initialize(peer); + + NS_RELEASE(instance); } } } @@ -1063,12 +1189,12 @@ printf("unable to find plugin to handle %s\n", aMimeType ? aMimeType : "(mime ty } } -nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst, - nsPluginWindow *aWindow, nsString& aURLSpec) +nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsString& aURLSpec, + nsIPluginInstanceOwner *aOwner) { nsresult rv; - rv = InstantiatePlugin(aMimeType, nsnull, aPluginInst); + rv = InstantiatePlugin(aMimeType, nsnull, aOwner); if ((rv != NS_OK) || (nsnull == aMimeType)) { @@ -1079,49 +1205,139 @@ nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsIPluginI { //we need to stream in enough to get the mime type... - rv = NewPluginStream(aURLSpec, aPluginInst, aWindow); + rv = NewPluginStream(aURLSpec, aOwner, nsnull); } else rv = NS_ERROR_FAILURE; } else { + nsIPluginInstance *instance = nsnull; + nsPluginWindow *window = nsnull; + //we got a plugin built, now stream - (*aPluginInst)->Start(); - (*aPluginInst)->SetWindow(aWindow); - NewPluginStream(aURLSpec, *aPluginInst, nsnull); + aOwner->GetInstance(instance); + aOwner->GetWindow(window); + + if (nsnull != instance) + { + instance->Start(); + aOwner->CreateWidget(); + instance->SetWindow(window); + + rv = NewPluginStream(aURLSpec, instance, nsnull); + + NS_RELEASE(instance); + } } return rv; } -NS_IMETHODIMP nsPluginHostImpl :: NewPluginStream(const nsString& aURL, nsIPluginInstance *aInstance, void *aNotifyData) +nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsString& aURLSpec, + nsIStreamListener *&aStreamListener, + nsIPluginInstanceOwner *aOwner) { - nsIURL *mURL; - nsPluginStreamListener *mListener = (nsPluginStreamListener *)new nsPluginStreamListener(); + nsresult rv; + nsIURL *url; - if (NS_OK == NS_NewURL(&mURL, aURL)) + //create a URL so that the instantiator can do file ext. + //based plugin lookups... + + rv = NS_NewURL(&url, aURLSpec); + + if (rv != NS_OK) + url = nsnull; + + rv = InstantiatePlugin(aMimeType, url, aOwner); + + NS_IF_RELEASE(url); + + if (NS_OK == rv) { - mListener->Initialize(mURL, aInstance, aNotifyData); - mURL->Open(mListener); + nsIPluginInstance *instance = nsnull; + nsPluginWindow *window = nsnull; + + //we got a plugin built, now stream + + aOwner->GetInstance(instance); + aOwner->GetWindow(window); + + if (nsnull != instance) + { + instance->Start(); + aOwner->CreateWidget(); + instance->SetWindow(window); + + rv = NewPluginStream(aStreamListener, instance, nsnull); + + NS_RELEASE(instance); + } } - return NS_OK; + return rv; } -NS_IMETHODIMP nsPluginHostImpl :: NewPluginStream(const nsString& aURL, nsIPluginInstance **aInstance, nsPluginWindow *aWindow) +NS_IMETHODIMP nsPluginHostImpl :: NewPluginStream(const nsString& aURL, + nsIPluginInstance *aInstance, + void *aNotifyData) { - nsIURL *mURL; - nsPluginStreamListener *mListener = (nsPluginStreamListener *)new nsPluginStreamListener(); + nsIURL *url; + nsPluginStreamListener *listener = (nsPluginStreamListener *)new nsPluginStreamListener(); + nsresult rv; - if (NS_OK == NS_NewURL(&mURL, aURL)) + rv = NS_NewURL(&url, aURL); + + if (NS_OK == rv) { - mListener->Initialize(mURL, aInstance, aWindow, (nsIPluginHost *)this); - mURL->Open(mListener); + rv = listener->Initialize(url, aInstance, aNotifyData); + + if (NS_OK == rv) + rv = url->Open(listener); + + NS_RELEASE(url); } - return NS_OK; + return rv; +} + +NS_IMETHODIMP nsPluginHostImpl :: NewPluginStream(const nsString& aURL, + nsIPluginInstanceOwner *aOwner, + void *aNotifyData) +{ + nsIURL *url; + nsPluginStreamListener *listener = (nsPluginStreamListener *)new nsPluginStreamListener(); + nsresult rv; + + rv = NS_NewURL(&url, aURL); + + if (NS_OK == rv) + { + rv = listener->Initialize(url, aOwner, (nsIPluginHost *)this, aNotifyData); + + if (NS_OK == rv) + rv = url->Open(listener); + + NS_RELEASE(url); + } + + return rv; +} + +NS_IMETHODIMP nsPluginHostImpl :: NewPluginStream(nsIStreamListener *&aStreamListener, + nsIPluginInstance *aInstance, + void *aNotifyData) +{ + nsPluginStreamListener *listener = (nsPluginStreamListener *)new nsPluginStreamListener(); + nsresult rv; + + rv = listener->Initialize(aInstance, aNotifyData); + + aStreamListener = (nsIStreamListener *)listener; + NS_IF_ADDREF(listener); + + return rv; } nsresult nsPluginHostImpl :: CreateInstance(nsISupports *aOuter, diff --git a/mozilla/modules/plugin/base/src/nsPluginHostImpl.h b/mozilla/modules/plugin/base/src/nsPluginHostImpl.h index 28d7c527d65..56309caaa70 100644 --- a/mozilla/modules/plugin/base/src/nsPluginHostImpl.h +++ b/mozilla/modules/plugin/base/src/nsPluginHostImpl.h @@ -47,7 +47,6 @@ public: char **mExtensionsArray; PRLibrary *mLibrary; nsIPlugin *mEntryPoint; - ns4xPlugin *mAdapter; PRUint32 mFlags; }; @@ -71,27 +70,24 @@ public: //nsIPluginManager interface + NS_IMETHOD + GetValue(nsPluginManagerVariable variable, void *value); + NS_IMETHOD ReloadPlugins(PRBool reloadPages); NS_IMETHOD UserAgent(const char* *resultingAgentString); - NS_IMETHOD - GetValue(nsPluginManagerVariable variable, void *value); - - NS_IMETHOD - SetValue(nsPluginManagerVariable variable, void *value); - //nsINetworkManager interface NS_IMETHOD - GetURL(nsISupports* peer, const char* url, const char* target, + GetURL(nsISupports* inst, const char* url, const char* target, void* notifyData = NULL, const char* altHost = NULL, const char* referrer = NULL, PRBool forceJSEnabled = PR_FALSE); NS_IMETHOD - PostURL(nsISupports* peer, const char* url, const char* target, + PostURL(nsISupports* inst, const char* url, const char* target, PRUint32 postDataLen, const char* postData, PRBool isFile = PR_FALSE, void* notifyData = NULL, const char* altHost = NULL, const char* referrer = NULL, @@ -106,21 +102,30 @@ public: NS_IMETHOD Init(void); + NS_IMETHOD + Destroy(void); + NS_IMETHOD LoadPlugins(void); NS_IMETHOD - InstantiatePlugin(const char *aMimeType, nsIURL *aURL, nsIPluginInstance ** aPluginInst); + InstantiatePlugin(const char *aMimeType, nsIURL *aURL, nsIPluginInstanceOwner *aOwner); NS_IMETHOD - InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst, - nsPluginWindow *aWindow, nsString& aURL); + InstantiatePlugin(const char *aMimeType, nsString& aURLSpec, nsIPluginInstanceOwner *aOwner); + + NS_IMETHOD + InstantiatePlugin(const char *aMimeType, nsString& aURLSpec, + nsIStreamListener *&aStreamListener, nsIPluginInstanceOwner *aOwner); NS_IMETHOD NewPluginStream(const nsString& aURL, nsIPluginInstance *aInstance, void *aNotifyData); NS_IMETHOD - NewPluginStream(const nsString& aURL, nsIPluginInstance **aInstance, nsPluginWindow *aWindow); + NewPluginStream(const nsString& aURL, nsIPluginInstanceOwner *aOwner, void *aNotifyData); + + NS_IMETHOD + NewPluginStream(nsIStreamListener *&aStreamListener, nsIPluginInstance *aInstance, void *aNotifyData); //nsIFactory interface diff --git a/mozilla/modules/plugin/base/src/nsPluginInstancePeer.cpp b/mozilla/modules/plugin/base/src/nsPluginInstancePeer.cpp index e230831911d..ca5cdc8aa8d 100644 --- a/mozilla/modules/plugin/base/src/nsPluginInstancePeer.cpp +++ b/mozilla/modules/plugin/base/src/nsPluginInstancePeer.cpp @@ -19,15 +19,29 @@ #include "nscore.h" #include "nsPluginInstancePeer.h" #include "nsIPluginInstance.h" +#include +#include "prmem.h" +#include "plstr.h" nsPluginInstancePeerImpl :: nsPluginInstancePeerImpl() { + NS_INIT_REFCNT(); + mInstance = nsnull; + mOwner = nsnull; + mMIMEType = nsnull; } nsPluginInstancePeerImpl :: ~nsPluginInstancePeerImpl() { mInstance = nsnull; + mOwner = nsnull; + + if (nsnull != mMIMEType) + { + PR_Free((void *)mMIMEType); + mMIMEType = nsnull; + } } NS_IMPL_ADDREF(nsPluginInstancePeerImpl); @@ -44,14 +58,14 @@ nsresult nsPluginInstancePeerImpl :: QueryInterface(const nsIID& iid, void** ins if (iid.Equals(kIPluginInstancePeerIID)) { - *instance = (void *)(nsISupports *)(nsIPluginInstancePeer *)this; + *instance = (void *)(nsIPluginInstancePeer *)this; AddRef(); return NS_OK; } if (iid.Equals(kIPluginTagInfoIID)) { - *instance = (void *)(nsISupports *)(nsIPluginTagInfo *)this; + *instance = (void *)(nsIPluginTagInfo *)this; AddRef(); return NS_OK; } @@ -68,54 +82,98 @@ nsresult nsPluginInstancePeerImpl :: QueryInterface(const nsIID& iid, void** ins NS_IMETHODIMP nsPluginInstancePeerImpl :: GetValue(nsPluginInstancePeerVariable variable, void *value) { +printf("instance peer getvalue %d called\n", variable); return NS_ERROR_FAILURE; } -NS_IMETHODIMP nsPluginInstancePeerImpl :: SetValue(nsPluginInstancePeerVariable variable, void *value) -{ - return NS_OK; -} - NS_IMETHODIMP nsPluginInstancePeerImpl :: GetMIMEType(nsMIMEType *result) { - *result = "model/vrml"; + if (nsnull == mMIMEType) + *result = ""; + else + *result = mMIMEType; + return NS_OK; } NS_IMETHODIMP nsPluginInstancePeerImpl :: GetMode(nsPluginMode *result) { - *result = nsPluginMode_Full; - return NS_OK; + if (nsnull != mOwner) + return mOwner->GetMode(result); + else + return NS_ERROR_FAILURE; } NS_IMETHODIMP nsPluginInstancePeerImpl :: NewStream(nsMIMEType type, const char* target, nsIOutputStream* *result) { +printf("instance peer newstream called\n"); return NS_OK; } NS_IMETHODIMP nsPluginInstancePeerImpl :: ShowStatus(const char* message) { +printf("instance peer showstatus called\n"); return NS_OK; } NS_IMETHODIMP nsPluginInstancePeerImpl :: GetAttributes(PRUint16& n, const char*const*& names, const char*const*& values) { - n = 0; - names = nsnull; - values = nsnull; - return NS_OK; + if (nsnull != mOwner) + return mOwner->GetAttributes(n, names, values); + else + { + n = 0; + names = nsnull; + values = nsnull; + return NS_ERROR_FAILURE; + } } NS_IMETHODIMP nsPluginInstancePeerImpl :: GetAttribute(const char* name, const char* *result) { - *result = 0; + if (nsnull != mOwner) + return mOwner->GetAttribute(name, result); + else + { + *result = ""; + return NS_ERROR_FAILURE; + } +} + +NS_IMETHODIMP nsPluginInstancePeerImpl :: SetWindowSize(PRUint32 width, PRUint32 height) +{ +printf("instance peer setwindowsize called\n"); return NS_OK; } -nsresult nsPluginInstancePeerImpl :: Initialize(nsIPluginInstance *aInstance) +nsresult nsPluginInstancePeerImpl :: Initialize(nsIPluginInstanceOwner *aOwner, + const nsMIMEType aMIMEType) { //don't add a ref to precent circular references... MMP - mInstance = aInstance; + mOwner = aOwner; + + aOwner->GetInstance(mInstance); + //release this one too... MMP + NS_IF_RELEASE(mInstance); + + if (nsnull != aMIMEType) + { + mMIMEType = (nsMIMEType)PR_Malloc(PL_strlen(aMIMEType) + 1); + + if (nsnull != mMIMEType) + PL_strcpy((char *)mMIMEType, aMIMEType); + } return NS_OK; } + +nsresult nsPluginInstancePeerImpl :: GetOwner(nsIPluginInstanceOwner *&aOwner) +{ + aOwner = mOwner; + NS_IF_ADDREF(mOwner); + + if (nsnull != mOwner) + return NS_OK; + else + return NS_ERROR_FAILURE; +} diff --git a/mozilla/modules/plugin/base/src/nsPluginInstancePeer.h b/mozilla/modules/plugin/base/src/nsPluginInstancePeer.h index aed1996112b..4a1d5d310b9 100644 --- a/mozilla/modules/plugin/base/src/nsPluginInstancePeer.h +++ b/mozilla/modules/plugin/base/src/nsPluginInstancePeer.h @@ -21,6 +21,7 @@ #include "nsIPluginInstancePeer.h" #include "nsIPluginTagInfo.h" +#include "nsIPluginInstanceOwner.h" class nsPluginInstancePeerImpl : public nsIPluginInstancePeer, public nsIPluginTagInfo { @@ -35,9 +36,6 @@ public: NS_IMETHOD GetValue(nsPluginInstancePeerVariable variable, void *value); - NS_IMETHOD - SetValue(nsPluginInstancePeerVariable variable, void *value); - NS_IMETHOD GetMIMEType(nsMIMEType *result); @@ -50,6 +48,9 @@ public: NS_IMETHOD ShowStatus(const char* message); + NS_IMETHOD + SetWindowSize(PRUint32 width, PRUint32 height); + //nsIPluginTagInfo interface NS_IMETHOD @@ -60,10 +61,15 @@ public: //locals - nsresult Initialize(nsIPluginInstance *aInstance); + nsresult Initialize(nsIPluginInstanceOwner *aInstance, + const nsMIMEType aMimeType); + + nsresult GetOwner(nsIPluginInstanceOwner *&aOwner); private: - nsIPluginInstance *mInstance; //we don't add a ref to this + nsIPluginInstance *mInstance; //we don't add a ref to this + nsIPluginInstanceOwner *mOwner; //we don't add a ref to this + nsMIMEType mMIMEType; }; #endif diff --git a/mozilla/modules/plugin/base/src/nsPluginStreamPeer.cpp b/mozilla/modules/plugin/base/src/nsPluginStreamPeer.cpp index e1f2cd711fe..c99c9c6678a 100644 --- a/mozilla/modules/plugin/base/src/nsPluginStreamPeer.cpp +++ b/mozilla/modules/plugin/base/src/nsPluginStreamPeer.cpp @@ -23,12 +23,15 @@ nsPluginStreamPeer :: nsPluginStreamPeer() { + NS_INIT_REFCNT(); + mURL = nsnull; mLength = 0; mLastMod = 0; mNotifyData = nsnull; mMIMEType = nsnull; mURLSpec = nsnull; + mReason = nsPluginReason_NoReason; } nsPluginStreamPeer :: ~nsPluginStreamPeer() @@ -122,7 +125,7 @@ NS_IMETHODIMP nsPluginStreamPeer :: GetNotifyData(void* *result) NS_IMETHODIMP nsPluginStreamPeer :: GetReason(nsPluginReason *result) { - *result = nsPluginReason_NoReason; + *result = mReason; return NS_OK; } @@ -157,3 +160,9 @@ nsresult nsPluginStreamPeer :: Initialize(nsIURL *aURL, PRUint32 aLength, return NS_OK; } + +nsresult nsPluginStreamPeer :: SetReason(nsPluginReason aReason) +{ + mReason = aReason; + return NS_OK; +} \ No newline at end of file diff --git a/mozilla/modules/plugin/base/src/nsPluginStreamPeer.h b/mozilla/modules/plugin/base/src/nsPluginStreamPeer.h index be7822fe88b..fa3967a8c6c 100644 --- a/mozilla/modules/plugin/base/src/nsPluginStreamPeer.h +++ b/mozilla/modules/plugin/base/src/nsPluginStreamPeer.h @@ -56,13 +56,16 @@ public: PRUint32 aLastMod, nsMIMEType aMIMEType, void *aNotifyData); + nsresult SetReason(nsPluginReason aReason); + private: - nsIURL *mURL; - PRUint32 mLength; - PRUint32 mLastMod; - void *mNotifyData; - nsMIMEType mMIMEType; - char *mURLSpec; + nsIURL *mURL; + PRUint32 mLength; + PRUint32 mLastMod; + void *mNotifyData; + nsMIMEType mMIMEType; + char *mURLSpec; + nsPluginReason mReason; }; #endif diff --git a/mozilla/modules/plugin/nglsrc/Makefile b/mozilla/modules/plugin/nglsrc/Makefile index cbd0c98efbc..e1caf6261ba 100644 --- a/mozilla/modules/plugin/nglsrc/Makefile +++ b/mozilla/modules/plugin/nglsrc/Makefile @@ -25,7 +25,8 @@ LIBRARY_NAME=raptorplugin EXPORTS = \ nsPluginsCID.h \ - nsIPluginHost.h + nsIPluginHost.h \ + nsIPluginInstanceOwner.h CPPSRCS = \ nsPluginHostImpl.cpp \ diff --git a/mozilla/modules/plugin/nglsrc/makefile.win b/mozilla/modules/plugin/nglsrc/makefile.win index 34a032a2777..3677b37368a 100644 --- a/mozilla/modules/plugin/nglsrc/makefile.win +++ b/mozilla/modules/plugin/nglsrc/makefile.win @@ -20,7 +20,8 @@ IGNORE_MANIFEST=1 EXPORTS = \ nsPluginsCID.h \ - nsIPluginHost.h + nsIPluginHost.h \ + nsIPluginInstanceOwner.h MAKE_OBJ_TYPE = DLL DLLNAME = raptorplugin diff --git a/mozilla/modules/plugin/nglsrc/ns4xPlugin.cpp b/mozilla/modules/plugin/nglsrc/ns4xPlugin.cpp index aa5b3fd09bd..12304120272 100644 --- a/mozilla/modules/plugin/nglsrc/ns4xPlugin.cpp +++ b/mozilla/modules/plugin/nglsrc/ns4xPlugin.cpp @@ -24,20 +24,6 @@ #include "nsIPluginStream.h" #include "ns4xPluginInstance.h" -//////////////////////////////////////////////////////////////////////// - -#ifdef XP_WIN -// XXX These are defined in platform specific FE directories right now :-/ -typedef NPError (__stdcall *NP_GETENTRYPOINTS)(NPPluginFuncs* pCallbacks); -typedef NPError (__stdcall *NP_PLUGININIT)(const NPNetscapeFuncs* pCallbacks); -typedef NPError (__stdcall *NP_PLUGINSHUTDOWN)(); -#else -typedef NPError (*NP_GETENTRYPOINTS)(NPPluginFuncs* pCallbacks); -typedef NPError (*NP_PLUGININIT)(const NPNetscapeFuncs* pCallbacks); -typedef NPError (*NP_PLUGINSHUTDOWN)(); -#endif /* XP_WIN */ - - //////////////////////////////////////////////////////////////////////// NPNetscapeFuncs ns4xPlugin::CALLBACKS; @@ -90,18 +76,17 @@ ns4xPlugin::CheckClassInitialized(void) //////////////////////////////////////////////////////////////////////// -ns4xPlugin::ns4xPlugin(NPPluginFuncs* callbacks) +ns4xPlugin::ns4xPlugin(NPPluginFuncs* callbacks, NP_PLUGINSHUTDOWN aShutdown) { NS_INIT_REFCNT(); + memcpy((void*) &fCallbacks, (void*) callbacks, sizeof(fCallbacks)); + fShutdownEntry = aShutdown; } ns4xPlugin::~ns4xPlugin(void) { - NS_IF_RELEASE(mPluginManager); - NS_IF_RELEASE(mNetworkManager); - NS_IF_RELEASE(mMalloc); } @@ -182,6 +167,9 @@ ns4xPlugin::CreatePlugin(PRLibrary *library, return NS_ERROR_FAILURE; #endif + NP_PLUGINSHUTDOWN pfnShutdown = + (NP_PLUGINSHUTDOWN)PR_FindSymbol(library, "NP_Shutdown"); + // the NP_Initialize entry point was misnamed as NP_PluginInit, // early in plugin project development. Its correct name is // documented now, and new developers expect it to work. However, @@ -201,9 +189,11 @@ ns4xPlugin::CreatePlugin(PRLibrary *library, if (pfnInitialize(&ns4xPlugin::CALLBACKS) != NS_OK) return NS_ERROR_UNEXPECTED; // XXX shoudl convert the 4.x error... - (*result) = new ns4xPlugin(&callbacks); + *result = new ns4xPlugin(&callbacks, pfnShutdown); - if ((*result) == NULL) + NS_ADDREF(*result); + + if (*result == NULL) return NS_ERROR_OUT_OF_MEMORY; return NS_OK; @@ -268,6 +258,15 @@ ns4xPlugin::Initialize(nsISupports* browserInterfaces) nsresult ns4xPlugin::Shutdown(void) { + if (nsnull != fShutdownEntry) + { +#ifdef NS_DEBUG +printf("shutting down plugin %08x\n", this); +#endif + fShutdownEntry(); + fShutdownEntry = nsnull; + } + NS_IF_RELEASE(mPluginManager); NS_IF_RELEASE(mNetworkManager); NS_IF_RELEASE(mMalloc); @@ -278,6 +277,7 @@ ns4xPlugin::Shutdown(void) nsresult ns4xPlugin::GetMIMEDescription(const char* *resultingDesc) { +printf("plugin getmimedescription called\n"); *resultingDesc = ""; return NS_OK; // XXX make a callback, etc. } @@ -285,12 +285,7 @@ ns4xPlugin::GetMIMEDescription(const char* *resultingDesc) nsresult ns4xPlugin::GetValue(nsPluginVariable variable, void *value) { - return NS_OK; -} - -nsresult -ns4xPlugin::SetValue(nsPluginVariable variable, void *value) -{ +printf("plugin getvalue %d called\n", variable); return NS_OK; } @@ -645,13 +640,26 @@ ns4xPlugin::_getvalue(NPP npp, NPNVariable variable, void *result) nsresult NP_EXPORT ns4xPlugin::_setvalue(NPP npp, NPPVariable variable, void *result) { - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + ns4xPluginInstance *inst = (ns4xPluginInstance *) npp->ndata; NS_ASSERTION(inst != NULL, "null instance"); if (inst == NULL) return NS_ERROR_FAILURE; // XXX + switch (variable) + { + case NPPVpluginWindowBool: + return inst->SetWindowless(*((NPBool *)result)); + + case NPPVpluginTransparentBool: + return inst->SetTransparent(*((NPBool *)result)); + + default: + return NS_OK; + } + +#if 0 nsIPluginInstancePeer *peer; if (NS_OK == inst->GetPeer(&peer)) @@ -666,6 +674,7 @@ ns4xPlugin::_setvalue(NPP npp, NPPVariable variable, void *result) } else return NS_ERROR_UNEXPECTED; +#endif } nsresult NP_EXPORT diff --git a/mozilla/modules/plugin/nglsrc/ns4xPlugin.h b/mozilla/modules/plugin/nglsrc/ns4xPlugin.h index e7b958d4721..69355e8e98a 100644 --- a/mozilla/modules/plugin/nglsrc/ns4xPlugin.h +++ b/mozilla/modules/plugin/nglsrc/ns4xPlugin.h @@ -43,13 +43,28 @@ //////////////////////////////////////////////////////////////////////// +// XXX These are defined in platform specific FE directories right now :-/ + +//BTW: this sucks rocks. +#ifdef XP_WIN +#define PLUGIN_ENTRYPOINT_CALL_TYPE __stdcall +#else +#define PLUGIN_ENTRYPOINT_CALL_TYPE +#endif + +typedef NPError (PLUGIN_ENTRYPOINT_CALL_TYPE *NP_GETENTRYPOINTS)(NPPluginFuncs* pCallbacks); +typedef NPError (PLUGIN_ENTRYPOINT_CALL_TYPE *NP_PLUGININIT)(const NPNetscapeFuncs* pCallbacks); +typedef NPError (PLUGIN_ENTRYPOINT_CALL_TYPE *NP_PLUGINSHUTDOWN)(); + +//////////////////////////////////////////////////////////////////////// + /** * A 5.0 wrapper for a 4.x style plugin. */ class ns4xPlugin : public nsILiveConnectPlugin { public: - ns4xPlugin(NPPluginFuncs* callbacks); + ns4xPlugin(NPPluginFuncs* callbacks, NP_PLUGINSHUTDOWN aShutdown); ~ns4xPlugin(void); NS_DECL_ISUPPORTS @@ -76,9 +91,6 @@ public: NS_IMETHOD GetValue(nsPluginVariable variable, void *value); - NS_IMETHOD - SetValue(nsPluginVariable variable, void *value); - //nsILiveConnectPlugin interface NS_IMETHOD @@ -207,6 +219,8 @@ protected: */ NPPluginFuncs fCallbacks; + NP_PLUGINSHUTDOWN fShutdownEntry; + /** * The browser-side callbacks that a 4.x-style plugin calls. */ diff --git a/mozilla/modules/plugin/nglsrc/ns4xPluginInstance.cpp b/mozilla/modules/plugin/nglsrc/ns4xPluginInstance.cpp index d01e5bfe0d9..6674ce3bb18 100644 --- a/mozilla/modules/plugin/nglsrc/ns4xPluginInstance.cpp +++ b/mozilla/modules/plugin/nglsrc/ns4xPluginInstance.cpp @@ -36,6 +36,9 @@ ns4xPluginInstance :: ns4xPluginInstance(NPPluginFuncs* callbacks) fNPP.ndata = this; fPeer = nsnull; + + mWindowless = PR_FALSE; + mTransparent = PR_FALSE; } @@ -140,6 +143,7 @@ NS_IMETHODIMP ns4xPluginInstance :: GetPeer(nsIPluginInstancePeer* *resultingPee { NS_ADDREF(fPeer); *resultingPeer = fPeer; + return NS_OK; } @@ -148,17 +152,30 @@ NS_IMETHODIMP ns4xPluginInstance::Start(void) // XXX At some point, we maybe should implement start and stop to // load/unload the 4.x plugin, just in case there are some plugins // that rely on that behavior... +printf("instance start called\n"); return NS_OK; } NS_IMETHODIMP ns4xPluginInstance::Stop(void) { +printf("instance stop called\n"); return NS_OK; } NS_IMETHODIMP ns4xPluginInstance::Destroy(void) { - return NS_OK; + nsresult error; + +printf("instance destroy called\n"); + if (fCallbacks->destroy == NULL) + return NS_ERROR_FAILURE; // XXX right error? + + NPSavedData *sdata; + + error = (nsresult)CallNPP_DestroyProc(fCallbacks->destroy, + &fNPP, &sdata); // saved data + + return error; } NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window) @@ -217,11 +234,13 @@ NS_IMETHODIMP ns4xPluginInstance::NewStream(nsIPluginStreamPeer* peer, nsIPlugin NS_IMETHODIMP ns4xPluginInstance::Print(nsPluginPrint* platformPrint) { +printf("instance print called\n"); return NS_OK; } NS_IMETHODIMP ns4xPluginInstance::HandleEvent(nsPluginEvent* event, PRBool* handled) { +printf("instance handleevent called\n"); *handled = PR_FALSE; return NS_OK; @@ -241,3 +260,37 @@ NS_IMETHODIMP ns4xPluginInstance::URLNotify(const char* url, const char* target, return NS_OK; //XXX this seems bad... } + +NS_IMETHODIMP ns4xPluginInstance :: GetValue(nsPluginInstanceVariable variable, void *value) +{ + nsresult rv = NS_OK; + + switch (variable) + { + case nsPluginInstanceVariable_WindowlessBool: + *(PRBool *)value = mWindowless; + break; + + case nsPluginInstanceVariable_TransparentBool: + *(PRBool *)value = mTransparent; + break; + + default: + rv = NS_ERROR_FAILURE; //XXX this is bad + } + + return rv; +} + +NS_IMETHODIMP ns4xPluginInstance :: SetWindowless(PRBool aWindowless) +{ + mWindowless = aWindowless; + return NS_OK; +} + +NS_IMETHODIMP ns4xPluginInstance :: SetTransparent(PRBool aTransparent) +{ + mTransparent = aTransparent; + return NS_OK; +} + diff --git a/mozilla/modules/plugin/nglsrc/ns4xPluginInstance.h b/mozilla/modules/plugin/nglsrc/ns4xPluginInstance.h index d9935010816..4c0a8270534 100644 --- a/mozilla/modules/plugin/nglsrc/ns4xPluginInstance.h +++ b/mozilla/modules/plugin/nglsrc/ns4xPluginInstance.h @@ -83,6 +83,9 @@ public: URLNotify(const char* url, const char* target, nsPluginReason reason, void* notifyData); + NS_IMETHOD + GetValue(nsPluginInstanceVariable variable, void *value); + //////////////////////////////////////////////////////////////////////// // ns4xPluginInstance-specific methods @@ -105,6 +108,12 @@ public: return NS_OK; }; + NS_IMETHOD + SetWindowless(PRBool aWindowless); + + NS_IMETHOD + SetTransparent(PRBool aTransparent); + protected: /** @@ -124,6 +133,12 @@ protected: * instance and the browser. */ NPP_t fNPP; + + //these are used to store the windowless properties + //which the browser will later query + + PRBool mWindowless; + PRBool mTransparent; }; diff --git a/mozilla/modules/plugin/nglsrc/ns4xPluginStream.cpp b/mozilla/modules/plugin/nglsrc/ns4xPluginStream.cpp index 5a1c52a9fcb..e60c894d753 100644 --- a/mozilla/modules/plugin/nglsrc/ns4xPluginStream.cpp +++ b/mozilla/modules/plugin/nglsrc/ns4xPluginStream.cpp @@ -28,6 +28,9 @@ ns4xPluginStream::ns4xPluginStream(void) { NS_INIT_REFCNT(); + fPeer = nsnull; + fInstance = nsnull; + // Initialize the 4.x interface structure memset(&fNPStream, 0, sizeof(fNPStream)); } @@ -98,7 +101,7 @@ NS_IMETHODIMP ns4xPluginStream::Initialize(ns4xPluginInstance* instance, NS_ASSERTION(fInstance != NULL, "null instance"); - fInstance->AddRef(); + NS_ADDREF(fInstance); NS_ASSERTION(fPeer != NULL, "null peer"); @@ -225,7 +228,6 @@ NS_IMETHODIMP ns4xPluginStream :: Close(void) { const NPPluginFuncs *callbacks; NPP npp; - nsresult rv; void *notifydata; fInstance->GetCallbacks(&callbacks); @@ -253,15 +255,7 @@ NS_IMETHODIMP ns4xPluginStream :: Close(void) notifydata); } - if (callbacks->destroystream == NULL) - return NS_OK; - - rv = (nsresult)CallNPP_DestroyStreamProc(callbacks->destroystream, - npp, - &fNPStream, - (NPReason)reason); - - return rv; + return NS_OK; } //////////////////////////////////////////////////////////////////////// diff --git a/mozilla/modules/plugin/nglsrc/nsIPluginHost.h b/mozilla/modules/plugin/nglsrc/nsIPluginHost.h index 690a24fca50..f169f620fa3 100644 --- a/mozilla/modules/plugin/nglsrc/nsIPluginHost.h +++ b/mozilla/modules/plugin/nglsrc/nsIPluginHost.h @@ -23,6 +23,8 @@ #include "nsplugindefs.h" #include "nsIFactory.h" #include "nsString.h" +#include "nsIPluginInstanceOwner.h" +#include "nsIStreamListener.h" class nsIURL; @@ -37,21 +39,29 @@ public: NS_IMETHOD Init(void) = 0; + NS_IMETHOD + Destroy(void) = 0; + NS_IMETHOD LoadPlugins(void) = 0; NS_IMETHOD - InstantiatePlugin(const char *aMimeType, nsIURL *aURL, nsIPluginInstance ** aPluginInst) = 0; + InstantiatePlugin(const char *aMimeType, nsIURL *aURL, nsIPluginInstanceOwner *aOwner) = 0; NS_IMETHOD - InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst, - nsPluginWindow *aWindow, nsString& aURL) = 0; + InstantiatePlugin(const char *aMimeType, nsString& aURLSpec, nsIPluginInstanceOwner *aOwner) = 0; + + NS_IMETHOD + InstantiatePlugin(const char *aMimeType, nsString& aURLSpec, nsIStreamListener *&aStreamListener, nsIPluginInstanceOwner *aOwner) = 0; NS_IMETHOD NewPluginStream(const nsString& aURL, nsIPluginInstance *aInstance, void *aNotifyData) = 0; NS_IMETHOD - NewPluginStream(const nsString& aURL, nsIPluginInstance **aInstance, nsPluginWindow *aWindow) = 0; + NewPluginStream(const nsString& aURL, nsIPluginInstanceOwner *aOwner, void *aNotifyData) = 0; + + NS_IMETHOD + NewPluginStream(nsIStreamListener *&aStreamListener, nsIPluginInstance *aInstance, void *aNotifyData) = 0; }; #endif diff --git a/mozilla/modules/plugin/nglsrc/nsIPluginInstanceOwner.h b/mozilla/modules/plugin/nglsrc/nsIPluginInstanceOwner.h new file mode 100644 index 00000000000..db85eb3c292 --- /dev/null +++ b/mozilla/modules/plugin/nglsrc/nsIPluginInstanceOwner.h @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsIPluginInstanceOwner_h___ +#define nsIPluginInstanceOwner_h___ + +#include "nsISupports.h" +#include "nsplugin.h" + +#define NS_IPLUGININSTANCEOWNER_IID \ +{ 0x18270870, 0x32f1, 0x11d2, \ +{ 0xa8, 0x30, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } } + +struct nsIPluginInstanceOwner : public nsISupports +{ +public: + + /** + * Let the owner know that an instance has been created + * + */ + NS_IMETHOD + SetInstance(nsIPluginInstance *aInstance) = 0; + + /** + * Get the instance associated with this owner. + * + */ + NS_IMETHOD + GetInstance(nsIPluginInstance *&aInstance) = 0; + + /** + * Get a handle to the window structure of the owner. + * This pointer cannot be made persistant by the caller. + * + */ + NS_IMETHOD + GetWindow(nsPluginWindow *&aWindow) = 0; + + /** + * Get the display mode for the plugin instance. + */ + NS_IMETHOD + GetMode(nsPluginMode *aMode) = 0; + + /** + * Get a ptr to the paired list of attribute names and values, + * returns the length of the array. + * + * Each name or value is a null-terminated string. + */ + NS_IMETHOD + GetAttributes(PRUint16& n, const char*const*& names, const char*const*& values) = 0; + + /** + * Gets the value for the named attribute. + * + * @param name - the name of the attribute to find + * @param result - the resulting attribute + * @result - NS_OK if this operation was successful, NS_ERROR_FAILURE if + * this operation failed. result is set to NULL if the attribute is not found + * else to the found value. + */ + NS_IMETHOD + GetAttribute(const char* name, const char* *result) = 0; + + /** + * Create a place for the plugin to live in the owner's + * environment. this may or may not create a window + * depending on the windowless state of the plugin instance. + * + */ + NS_IMETHOD + CreateWidget(void) = 0; + + /** + * Called when there is a valid target so that the proper + * frame can be updated with new content. will not be called + * with nsnull aTarget. + * + */ + NS_IMETHOD + GetURL(const char *aURL, const char *aTarget, void *aPostData) = 0; +}; + +#endif diff --git a/mozilla/modules/plugin/nglsrc/nsPluginHostImpl.cpp b/mozilla/modules/plugin/nglsrc/nsPluginHostImpl.cpp index c499a1e3542..2258733c19a 100644 --- a/mozilla/modules/plugin/nglsrc/nsPluginHostImpl.cpp +++ b/mozilla/modules/plugin/nglsrc/nsPluginHostImpl.cpp @@ -27,9 +27,12 @@ #include "nsIStreamListener.h" #include "nsIURL.h" #include "nsIInputStream.h" +#include "prprf.h" +#include "gui.h" #ifdef XP_PC #include "windows.h" +#include "winbase.h" #endif static NS_DEFINE_IID(kIPluginInstanceIID, NS_IPLUGININSTANCE_IID); @@ -63,6 +66,8 @@ nsPluginTag :: nsPluginTag() nsPluginTag :: ~nsPluginTag() { + NS_IF_RELEASE(mEntryPoint); + if (nsnull != mName) { PR_Free(mName); @@ -116,8 +121,6 @@ nsPluginTag :: ~nsPluginTag() PR_UnloadLibrary(mLibrary); mLibrary = nsnull; } - - mEntryPoint = nsnull; } class nsPluginStreamListener : public nsIStreamListener @@ -148,39 +151,40 @@ public: //locals nsresult Initialize(nsIURL *aURL, nsIPluginInstance *aInstance, void *aNotifyData); - nsresult Initialize(nsIURL *aURL, nsIPluginInstance **aInstance, - nsPluginWindow *aWindow, nsIPluginHost *aHost); + nsresult Initialize(nsIURL *aURL, nsIPluginInstanceOwner *aOwner, + nsIPluginHost *aHost, void *aNotifyData); + nsresult Initialize(nsIPluginInstance *aInstance, void *aNotifyData); private: - nsIURL *mURL; - nsPluginStreamPeer *mPeer; - nsIPluginInstance *mInstance; - nsIPluginInstance **mFarInstance; - PRBool mBound; - nsIPluginStream *mStream; - char *mMIMEType; - PRUint8 *mBuffer; - PRUint32 mBufSize; - void *mNotifyData; - nsPluginWindow *mWindow; - nsIPluginHost *mHost; - PRInt32 mLength; - PRBool mGotProgress; + nsIURL *mURL; + nsPluginStreamPeer *mPeer; + nsIPluginInstanceOwner *mOwner; + nsIPluginInstance *mInstance; + PRBool mBound; + nsIPluginStream *mStream; + char *mMIMEType; + PRUint8 *mBuffer; + PRUint32 mBufSize; + void *mNotifyData; + nsIPluginHost *mHost; + PRInt32 mLength; + PRBool mGotProgress; }; nsPluginStreamListener :: nsPluginStreamListener() { + NS_INIT_REFCNT(); + mURL = nsnull; mPeer = nsnull; + mOwner = nsnull; mInstance = nsnull; - mFarInstance = nsnull; mBound = PR_FALSE; mStream = nsnull; mMIMEType = nsnull; mBuffer = nsnull; mBufSize = 0; mNotifyData = nsnull; - mWindow = nsnull; mHost = nsnull; mLength = 0; mGotProgress = PR_FALSE; @@ -188,10 +192,14 @@ nsPluginStreamListener :: nsPluginStreamListener() nsPluginStreamListener :: ~nsPluginStreamListener() { +#ifdef NS_DEBUG +printf("killing stream for %s\n", mURL ? mURL->GetSpec() : "(unknown URL)"); +#endif NS_IF_RELEASE(mURL); - NS_IF_RELEASE(mPeer); + NS_IF_RELEASE(mOwner); NS_IF_RELEASE(mInstance); NS_IF_RELEASE(mStream); + NS_IF_RELEASE(mPeer); if (nsnull != mMIMEType) { @@ -206,8 +214,6 @@ nsPluginStreamListener :: ~nsPluginStreamListener() } mNotifyData = nsnull; - mWindow = nsnull; - mFarInstance = nsnull; NS_IF_RELEASE(mHost); } @@ -249,6 +255,9 @@ nsresult nsPluginStreamListener :: QueryInterface(const nsIID& aIID, nsresult nsPluginStreamListener :: Initialize(nsIURL *aURL, nsIPluginInstance *aInstance, void *aNotifyData) { +#ifdef NS_DEBUG +printf("created stream for %s\n", aURL->GetSpec()); +#endif mURL = aURL; NS_ADDREF(mURL); @@ -260,15 +269,17 @@ nsresult nsPluginStreamListener :: Initialize(nsIURL *aURL, nsIPluginInstance *a return NS_OK; } -nsresult nsPluginStreamListener :: Initialize(nsIURL *aURL, nsIPluginInstance **aInstance, - nsPluginWindow *aWindow, nsIPluginHost *aHost) +nsresult nsPluginStreamListener :: Initialize(nsIURL *aURL, nsIPluginInstanceOwner *aOwner, + nsIPluginHost *aHost, void *aNotifyData) { +#ifdef NS_DEBUG +printf("created stream for %s\n", aURL->GetSpec()); +#endif mURL = aURL; NS_ADDREF(mURL); - mFarInstance = aInstance; - - mWindow = aWindow; + mOwner = aOwner; + NS_ADDREF(mOwner); mHost = aHost; NS_IF_ADDREF(mHost); @@ -276,6 +287,19 @@ nsresult nsPluginStreamListener :: Initialize(nsIURL *aURL, nsIPluginInstance ** return NS_OK; } +nsresult nsPluginStreamListener :: Initialize(nsIPluginInstance *aInstance, void *aNotifyData) +{ +#ifdef NS_DEBUG +printf("created stream for (unknown URL)\n"); +#endif + mInstance = aInstance; + NS_ADDREF(mInstance); + + mNotifyData = aNotifyData; + + return NS_OK; +} + NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char *aContentType) { nsresult rv = NS_OK; @@ -286,7 +310,7 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char mMIMEType = (char *)PR_Malloc(len + 1); if (nsnull != mMIMEType) - strcpy(mMIMEType, aContentType); + PL_strcpy(mMIMEType, aContentType); else rv = NS_ERROR_OUT_OF_MEMORY; } @@ -294,23 +318,39 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char //now that we have the mime type, see if we need //to load a plugin... - if ((nsnull == mInstance) && (nsnull != mFarInstance) && - (nsnull != mHost) && (nsnull != mWindow)) + nsIPluginInstance *instance = nsnull; + nsPluginWindow *window = nsnull; + + if ((nsnull == mInstance) && (nsnull != mOwner)) { - rv = mHost->InstantiatePlugin(aContentType, aURL, mFarInstance); + mOwner->GetInstance(instance); + mOwner->GetWindow(window); - if (NS_OK == rv) + if ((nsnull == instance) && (nsnull != mHost) && (nsnull != window)) { - mInstance = *mFarInstance; - NS_ADDREF(mInstance); + rv = mHost->InstantiatePlugin(aContentType, aURL, mOwner); - (*mFarInstance)->Start(); - (*mFarInstance)->SetWindow(mWindow); + if (NS_OK == rv) + { + mOwner->GetInstance(instance); + + if (nsnull != instance) + { + instance->Start(); + mOwner->CreateWidget(); + instance->SetWindow(window); + } + } } } + else + { + instance = mInstance; + NS_ADDREF(instance); + } if ((PR_TRUE == mGotProgress) && (nsnull == mPeer) && - (nsnull != mInstance) && (PR_FALSE == mBound)) + (nsnull != instance) && (PR_FALSE == mBound)) { //need to create new peer and and tell plugin that we have new stream... @@ -319,9 +359,11 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char NS_ADDREF(mPeer); mPeer->Initialize(aURL, mLength, 0, aContentType, mNotifyData); - mInstance->NewStream(mPeer, &mStream); + instance->NewStream(mPeer, &mStream); } + NS_IF_RELEASE(instance); + mBound = PR_TRUE; return rv; @@ -329,16 +371,31 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStartBinding(nsIURL* aURL, const char NS_IMETHODIMP nsPluginStreamListener :: OnProgress(nsIURL* aURL, PRInt32 aProgress, PRInt32 aProgressMax) { - if ((aProgress == 0) && (nsnull == mPeer) && (nsnull != mInstance)) + if ((aProgress == 0) && (nsnull == mPeer)) { - //need to create new peer and and tell plugin that we have new stream... + nsIPluginInstance *instance = nsnull; - mPeer = (nsPluginStreamPeer *)new nsPluginStreamPeer(); + if (nsnull == mInstance) + mOwner->GetInstance(instance); + else + { + instance = mInstance; + NS_ADDREF(instance); + } - NS_ADDREF(mPeer); + if (nsnull != instance) + { + //need to create new peer and and tell plugin that we have new stream... - mPeer->Initialize(aURL, aProgressMax, 0, mMIMEType, mNotifyData); - mInstance->NewStream(mPeer, &mStream); + mPeer = (nsPluginStreamPeer *)new nsPluginStreamPeer(); + + NS_ADDREF(mPeer); + + mPeer->Initialize(aURL, aProgressMax, 0, mMIMEType, mNotifyData); + instance->NewStream(mPeer, &mStream); + + NS_RELEASE(instance); + } } mLength = aProgressMax; @@ -354,10 +411,26 @@ NS_IMETHODIMP nsPluginStreamListener :: OnStatus(nsIURL* aURL, const nsString &a NS_IMETHODIMP nsPluginStreamListener :: OnStopBinding(nsIURL* aURL, PRInt32 aStatus, const nsString &aMsg) { + nsresult rv; + + //XXX this is incomplete... MMP + + if (nsnull != mPeer) + { + if (aStatus == NS_BINDING_SUCCEEDED) + mPeer->SetReason(nsPluginReason_Done); + else + mPeer->SetReason(nsPluginReason_UserBreak); + + rv = NS_OK; + } + else + rv = NS_ERROR_UNEXPECTED; + if (nsnull != mStream) mStream->Close(); - return NS_OK; + return rv; } NS_IMETHODIMP nsPluginStreamListener :: GetBindInfo(nsIURL* aURL) @@ -389,10 +462,14 @@ NS_IMETHODIMP nsPluginStreamListener :: OnDataAvailable(nsIURL* aURL, nsIInputSt nsPluginHostImpl :: nsPluginHostImpl() { + NS_INIT_REFCNT(); } nsPluginHostImpl :: ~nsPluginHostImpl() { +#ifdef NS_DEBUG +printf("killing plugin host\n"); +#endif if (nsnull != mPluginPath) { PR_Free(mPluginPath); @@ -465,6 +542,12 @@ nsresult nsPluginHostImpl :: QueryInterface(const nsIID& aIID, return NS_NOINTERFACE; } +NS_IMETHODIMP nsPluginHostImpl :: GetValue(nsPluginManagerVariable variable, void *value) +{ +printf("manager getvalue %d called\n", variable); + return NS_OK; +} + nsresult nsPluginHostImpl :: ReloadPlugins(PRBool reloadPages) { return LoadPlugins(); @@ -473,41 +556,61 @@ nsresult nsPluginHostImpl :: ReloadPlugins(PRBool reloadPages) //XXX need to find out score on this one... MMP nsresult nsPluginHostImpl :: UserAgent(const char **retstring) { - *retstring = "NGLayout"; + *retstring = (const char *)"Mozilla/4.05 [en] (Windows;I)"; return NS_OK; } -nsresult nsPluginHostImpl :: GetValue(nsPluginManagerVariable variable, void *value) -{ - return NS_OK; -} - -nsresult nsPluginHostImpl :: SetValue(nsPluginManagerVariable variable, void *value) -{ - return NS_OK; -} - -NS_IMETHODIMP nsPluginHostImpl :: GetURL(nsISupports* peer, const char* url, +NS_IMETHODIMP nsPluginHostImpl :: GetURL(nsISupports* inst, const char* url, const char* target, void* notifyData, const char* altHost, const char* referrer, PRBool forceJSEnabled) { - nsAutoString string = nsAutoString(url); - nsIPluginInstance *inst; - nsresult rv; + nsAutoString string = nsAutoString(url); + nsIPluginInstance *instance; + nsresult rv; - rv = peer->QueryInterface(kIPluginInstanceIID, (void **)&inst); + rv = inst->QueryInterface(kIPluginInstanceIID, (void **)&instance); if (NS_OK == rv) { - NewPluginStream(string, inst, notifyData); - NS_RELEASE(inst); + if (nsnull != target) + { + nsPluginInstancePeerImpl *peer; + + rv = instance->GetPeer((nsIPluginInstancePeer **)&peer); + + if (NS_OK == rv) + { + nsIPluginInstanceOwner *owner; + + rv = peer->GetOwner(owner); + + if (NS_OK == rv) + { + if ((0 == PL_strcmp(target, "newwindow")) || + (0 == PL_strcmp(target, "_new"))) + target = "_blank"; + else if (0 == PL_strcmp(target, "_current")) + target = "_self"; + + rv = owner->GetURL(url, target, nsnull); + NS_RELEASE(owner); + } + + NS_RELEASE(peer); + } + } + + if ((nsnull != notifyData) || (nsnull == target)) + rv = NewPluginStream(string, instance, notifyData); + + NS_RELEASE(instance); } return rv; } -NS_IMETHODIMP nsPluginHostImpl :: PostURL(nsISupports* peer, +NS_IMETHODIMP nsPluginHostImpl :: PostURL(nsISupports* inst, const char* url, const char* target, PRUint32 postDataLen, const char* postData, PRBool isFile, void* notifyData, @@ -515,20 +618,22 @@ NS_IMETHODIMP nsPluginHostImpl :: PostURL(nsISupports* peer, PRBool forceJSEnabled, PRUint32 postHeadersLength, const char* postHeaders) { +printf("network manager posturl called\n"); return NS_ERROR_NOT_IMPLEMENTED; } -NS_IMETHODIMP -nsPluginHostImpl::FindProxyForURL(const char* url, char* *result) +NS_IMETHODIMP nsPluginHostImpl :: FindProxyForURL(const char* url, char* *result) { +printf("network manager findproxyforurl called\n"); return NS_ERROR_NOT_IMPLEMENTED; } nsresult nsPluginHostImpl :: Init(void) { - nsresult rv; + nsresult rv; nsISupports *object; +// rv = nsMalloc::Create(nsnull, kIMallocIID, (void **)&mMalloc); rv = nsMalloc::Create(nsnull, kIMallocIID, (void **)&object); if (NS_OK == rv) @@ -540,6 +645,21 @@ nsresult nsPluginHostImpl :: Init(void) return rv; } +nsresult nsPluginHostImpl :: Destroy(void) +{ + nsPluginTag *plug = mPlugins; + + while (nsnull != plug) + { + if (nsnull != plug->mEntryPoint) + plug->mEntryPoint->Shutdown(); + + plug = plug->mNext; + } + + return NS_OK; +} + nsresult nsPluginHostImpl :: LoadPlugins(void) { #ifdef XP_PC @@ -610,7 +730,7 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) if (nsnull != mPluginPath) { - strcpy(mPluginPath, path); + PL_strcpy(mPluginPath, path); mPluginPath[pathlen] = '\\'; mPluginPath[pathlen + 1] = 0; @@ -625,7 +745,7 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) while (dent = PR_ReadDir(dir, PR_SKIP_BOTH)) { - PRInt32 len = strlen(dent->name); + PRInt32 len = PL_strlen(dent->name); if (len > 6) //np*.dll { @@ -634,8 +754,8 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) { PRLibrary *plugin; - strcpy(path, mPluginPath); - strcat(path, dent->name); + PL_strcpy(path, mPluginPath); + PL_strcat(path, dent->name); plugin = PR_LoadLibrary(path); @@ -673,7 +793,7 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) if (nsnull == plugintag->mName) break; else - strcpy(plugintag->mName, dent->name); + PL_strcpy(plugintag->mName, dent->name); ::VerQueryValue(verbuf, TEXT("\\StringFileInfo\\040904E4\\FileDescription"), @@ -688,7 +808,7 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) if (nsnull == plugintag->mDescription) break; else - strcpy(plugintag->mDescription, buf); + PL_strcpy(plugintag->mDescription, buf); } ::VerQueryValue(verbuf, @@ -704,7 +824,7 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) if (nsnull == plugintag->mMimeType) break; else - strcpy(plugintag->mMimeType, buf); + PL_strcpy(plugintag->mMimeType, buf); buf = plugintag->mMimeType; @@ -758,7 +878,7 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) if (nsnull == plugintag->mMimeDescription) break; else - strcpy(plugintag->mMimeDescription, buf); + PL_strcpy(plugintag->mMimeDescription, buf); buf = plugintag->mMimeDescription; @@ -813,7 +933,7 @@ nsresult nsPluginHostImpl :: LoadPlugins(void) if (nsnull == plugintag->mExtensions) break; else - strcpy(plugintag->mExtensions, buf); + PL_strcpy(plugintag->mExtensions, buf); buf = plugintag->mExtensions; @@ -897,7 +1017,7 @@ printf("plugin %s added to list %s\n", plugintag->mName, (plugintag->mFlags & NS } nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsIURL *aURL, - nsIPluginInstance ** aPluginInst) + nsIPluginInstanceOwner *aOwner) { nsPluginTag *plugins = nsnull; PRInt32 variants, cnt; @@ -1001,8 +1121,8 @@ printf("found plugin via extension %s\n", ext); { char path[2000]; - strcpy(path, mPluginPath); - strcat(path, plugins->mName); + PL_strcpy(path, mPluginPath); + PL_strcat(path, plugins->mName); plugins->mLibrary = PR_LoadLibrary(path); #ifdef NS_DEBUG @@ -1032,17 +1152,23 @@ printf("result of creating plugin adapter: %d\n", rv); if (nsnull != plugins->mEntryPoint) { + nsIPluginInstance *instance; + //create an instance - if (NS_OK == plugins->mEntryPoint->CreateInstance(nsnull, kIPluginInstanceIID, (void **)aPluginInst)) + if (NS_OK == plugins->mEntryPoint->CreateInstance(nsnull, kIPluginInstanceIID, (void **)&instance)) { #ifdef NS_DEBUG -printf("successfully created plugin instance\n"); +printf("successfully created plugin instance %08x for %s, mimetype %s\n", instance, plugins->mName, aMimeType ? aMimeType : "(none)"); #endif + aOwner->SetInstance(instance); + nsPluginInstancePeerImpl *peer = new nsPluginInstancePeerImpl(); - peer->Initialize(*aPluginInst); //this will not add a ref to the instance. MMP - (*aPluginInst)->Initialize(peer); + peer->Initialize(aOwner, aMimeType); //this will not add a ref to the instance (or owner). MMP + instance->Initialize(peer); + + NS_RELEASE(instance); } } } @@ -1063,12 +1189,12 @@ printf("unable to find plugin to handle %s\n", aMimeType ? aMimeType : "(mime ty } } -nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst, - nsPluginWindow *aWindow, nsString& aURLSpec) +nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsString& aURLSpec, + nsIPluginInstanceOwner *aOwner) { nsresult rv; - rv = InstantiatePlugin(aMimeType, nsnull, aPluginInst); + rv = InstantiatePlugin(aMimeType, nsnull, aOwner); if ((rv != NS_OK) || (nsnull == aMimeType)) { @@ -1079,49 +1205,139 @@ nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsIPluginI { //we need to stream in enough to get the mime type... - rv = NewPluginStream(aURLSpec, aPluginInst, aWindow); + rv = NewPluginStream(aURLSpec, aOwner, nsnull); } else rv = NS_ERROR_FAILURE; } else { + nsIPluginInstance *instance = nsnull; + nsPluginWindow *window = nsnull; + //we got a plugin built, now stream - (*aPluginInst)->Start(); - (*aPluginInst)->SetWindow(aWindow); - NewPluginStream(aURLSpec, *aPluginInst, nsnull); + aOwner->GetInstance(instance); + aOwner->GetWindow(window); + + if (nsnull != instance) + { + instance->Start(); + aOwner->CreateWidget(); + instance->SetWindow(window); + + rv = NewPluginStream(aURLSpec, instance, nsnull); + + NS_RELEASE(instance); + } } return rv; } -NS_IMETHODIMP nsPluginHostImpl :: NewPluginStream(const nsString& aURL, nsIPluginInstance *aInstance, void *aNotifyData) +nsresult nsPluginHostImpl :: InstantiatePlugin(const char *aMimeType, nsString& aURLSpec, + nsIStreamListener *&aStreamListener, + nsIPluginInstanceOwner *aOwner) { - nsIURL *mURL; - nsPluginStreamListener *mListener = (nsPluginStreamListener *)new nsPluginStreamListener(); + nsresult rv; + nsIURL *url; - if (NS_OK == NS_NewURL(&mURL, aURL)) + //create a URL so that the instantiator can do file ext. + //based plugin lookups... + + rv = NS_NewURL(&url, aURLSpec); + + if (rv != NS_OK) + url = nsnull; + + rv = InstantiatePlugin(aMimeType, url, aOwner); + + NS_IF_RELEASE(url); + + if (NS_OK == rv) { - mListener->Initialize(mURL, aInstance, aNotifyData); - mURL->Open(mListener); + nsIPluginInstance *instance = nsnull; + nsPluginWindow *window = nsnull; + + //we got a plugin built, now stream + + aOwner->GetInstance(instance); + aOwner->GetWindow(window); + + if (nsnull != instance) + { + instance->Start(); + aOwner->CreateWidget(); + instance->SetWindow(window); + + rv = NewPluginStream(aStreamListener, instance, nsnull); + + NS_RELEASE(instance); + } } - return NS_OK; + return rv; } -NS_IMETHODIMP nsPluginHostImpl :: NewPluginStream(const nsString& aURL, nsIPluginInstance **aInstance, nsPluginWindow *aWindow) +NS_IMETHODIMP nsPluginHostImpl :: NewPluginStream(const nsString& aURL, + nsIPluginInstance *aInstance, + void *aNotifyData) { - nsIURL *mURL; - nsPluginStreamListener *mListener = (nsPluginStreamListener *)new nsPluginStreamListener(); + nsIURL *url; + nsPluginStreamListener *listener = (nsPluginStreamListener *)new nsPluginStreamListener(); + nsresult rv; - if (NS_OK == NS_NewURL(&mURL, aURL)) + rv = NS_NewURL(&url, aURL); + + if (NS_OK == rv) { - mListener->Initialize(mURL, aInstance, aWindow, (nsIPluginHost *)this); - mURL->Open(mListener); + rv = listener->Initialize(url, aInstance, aNotifyData); + + if (NS_OK == rv) + rv = url->Open(listener); + + NS_RELEASE(url); } - return NS_OK; + return rv; +} + +NS_IMETHODIMP nsPluginHostImpl :: NewPluginStream(const nsString& aURL, + nsIPluginInstanceOwner *aOwner, + void *aNotifyData) +{ + nsIURL *url; + nsPluginStreamListener *listener = (nsPluginStreamListener *)new nsPluginStreamListener(); + nsresult rv; + + rv = NS_NewURL(&url, aURL); + + if (NS_OK == rv) + { + rv = listener->Initialize(url, aOwner, (nsIPluginHost *)this, aNotifyData); + + if (NS_OK == rv) + rv = url->Open(listener); + + NS_RELEASE(url); + } + + return rv; +} + +NS_IMETHODIMP nsPluginHostImpl :: NewPluginStream(nsIStreamListener *&aStreamListener, + nsIPluginInstance *aInstance, + void *aNotifyData) +{ + nsPluginStreamListener *listener = (nsPluginStreamListener *)new nsPluginStreamListener(); + nsresult rv; + + rv = listener->Initialize(aInstance, aNotifyData); + + aStreamListener = (nsIStreamListener *)listener; + NS_IF_ADDREF(listener); + + return rv; } nsresult nsPluginHostImpl :: CreateInstance(nsISupports *aOuter, diff --git a/mozilla/modules/plugin/nglsrc/nsPluginHostImpl.h b/mozilla/modules/plugin/nglsrc/nsPluginHostImpl.h index 28d7c527d65..56309caaa70 100644 --- a/mozilla/modules/plugin/nglsrc/nsPluginHostImpl.h +++ b/mozilla/modules/plugin/nglsrc/nsPluginHostImpl.h @@ -47,7 +47,6 @@ public: char **mExtensionsArray; PRLibrary *mLibrary; nsIPlugin *mEntryPoint; - ns4xPlugin *mAdapter; PRUint32 mFlags; }; @@ -71,27 +70,24 @@ public: //nsIPluginManager interface + NS_IMETHOD + GetValue(nsPluginManagerVariable variable, void *value); + NS_IMETHOD ReloadPlugins(PRBool reloadPages); NS_IMETHOD UserAgent(const char* *resultingAgentString); - NS_IMETHOD - GetValue(nsPluginManagerVariable variable, void *value); - - NS_IMETHOD - SetValue(nsPluginManagerVariable variable, void *value); - //nsINetworkManager interface NS_IMETHOD - GetURL(nsISupports* peer, const char* url, const char* target, + GetURL(nsISupports* inst, const char* url, const char* target, void* notifyData = NULL, const char* altHost = NULL, const char* referrer = NULL, PRBool forceJSEnabled = PR_FALSE); NS_IMETHOD - PostURL(nsISupports* peer, const char* url, const char* target, + PostURL(nsISupports* inst, const char* url, const char* target, PRUint32 postDataLen, const char* postData, PRBool isFile = PR_FALSE, void* notifyData = NULL, const char* altHost = NULL, const char* referrer = NULL, @@ -106,21 +102,30 @@ public: NS_IMETHOD Init(void); + NS_IMETHOD + Destroy(void); + NS_IMETHOD LoadPlugins(void); NS_IMETHOD - InstantiatePlugin(const char *aMimeType, nsIURL *aURL, nsIPluginInstance ** aPluginInst); + InstantiatePlugin(const char *aMimeType, nsIURL *aURL, nsIPluginInstanceOwner *aOwner); NS_IMETHOD - InstantiatePlugin(const char *aMimeType, nsIPluginInstance ** aPluginInst, - nsPluginWindow *aWindow, nsString& aURL); + InstantiatePlugin(const char *aMimeType, nsString& aURLSpec, nsIPluginInstanceOwner *aOwner); + + NS_IMETHOD + InstantiatePlugin(const char *aMimeType, nsString& aURLSpec, + nsIStreamListener *&aStreamListener, nsIPluginInstanceOwner *aOwner); NS_IMETHOD NewPluginStream(const nsString& aURL, nsIPluginInstance *aInstance, void *aNotifyData); NS_IMETHOD - NewPluginStream(const nsString& aURL, nsIPluginInstance **aInstance, nsPluginWindow *aWindow); + NewPluginStream(const nsString& aURL, nsIPluginInstanceOwner *aOwner, void *aNotifyData); + + NS_IMETHOD + NewPluginStream(nsIStreamListener *&aStreamListener, nsIPluginInstance *aInstance, void *aNotifyData); //nsIFactory interface diff --git a/mozilla/modules/plugin/nglsrc/nsPluginInstancePeer.cpp b/mozilla/modules/plugin/nglsrc/nsPluginInstancePeer.cpp index e230831911d..ca5cdc8aa8d 100644 --- a/mozilla/modules/plugin/nglsrc/nsPluginInstancePeer.cpp +++ b/mozilla/modules/plugin/nglsrc/nsPluginInstancePeer.cpp @@ -19,15 +19,29 @@ #include "nscore.h" #include "nsPluginInstancePeer.h" #include "nsIPluginInstance.h" +#include +#include "prmem.h" +#include "plstr.h" nsPluginInstancePeerImpl :: nsPluginInstancePeerImpl() { + NS_INIT_REFCNT(); + mInstance = nsnull; + mOwner = nsnull; + mMIMEType = nsnull; } nsPluginInstancePeerImpl :: ~nsPluginInstancePeerImpl() { mInstance = nsnull; + mOwner = nsnull; + + if (nsnull != mMIMEType) + { + PR_Free((void *)mMIMEType); + mMIMEType = nsnull; + } } NS_IMPL_ADDREF(nsPluginInstancePeerImpl); @@ -44,14 +58,14 @@ nsresult nsPluginInstancePeerImpl :: QueryInterface(const nsIID& iid, void** ins if (iid.Equals(kIPluginInstancePeerIID)) { - *instance = (void *)(nsISupports *)(nsIPluginInstancePeer *)this; + *instance = (void *)(nsIPluginInstancePeer *)this; AddRef(); return NS_OK; } if (iid.Equals(kIPluginTagInfoIID)) { - *instance = (void *)(nsISupports *)(nsIPluginTagInfo *)this; + *instance = (void *)(nsIPluginTagInfo *)this; AddRef(); return NS_OK; } @@ -68,54 +82,98 @@ nsresult nsPluginInstancePeerImpl :: QueryInterface(const nsIID& iid, void** ins NS_IMETHODIMP nsPluginInstancePeerImpl :: GetValue(nsPluginInstancePeerVariable variable, void *value) { +printf("instance peer getvalue %d called\n", variable); return NS_ERROR_FAILURE; } -NS_IMETHODIMP nsPluginInstancePeerImpl :: SetValue(nsPluginInstancePeerVariable variable, void *value) -{ - return NS_OK; -} - NS_IMETHODIMP nsPluginInstancePeerImpl :: GetMIMEType(nsMIMEType *result) { - *result = "model/vrml"; + if (nsnull == mMIMEType) + *result = ""; + else + *result = mMIMEType; + return NS_OK; } NS_IMETHODIMP nsPluginInstancePeerImpl :: GetMode(nsPluginMode *result) { - *result = nsPluginMode_Full; - return NS_OK; + if (nsnull != mOwner) + return mOwner->GetMode(result); + else + return NS_ERROR_FAILURE; } NS_IMETHODIMP nsPluginInstancePeerImpl :: NewStream(nsMIMEType type, const char* target, nsIOutputStream* *result) { +printf("instance peer newstream called\n"); return NS_OK; } NS_IMETHODIMP nsPluginInstancePeerImpl :: ShowStatus(const char* message) { +printf("instance peer showstatus called\n"); return NS_OK; } NS_IMETHODIMP nsPluginInstancePeerImpl :: GetAttributes(PRUint16& n, const char*const*& names, const char*const*& values) { - n = 0; - names = nsnull; - values = nsnull; - return NS_OK; + if (nsnull != mOwner) + return mOwner->GetAttributes(n, names, values); + else + { + n = 0; + names = nsnull; + values = nsnull; + return NS_ERROR_FAILURE; + } } NS_IMETHODIMP nsPluginInstancePeerImpl :: GetAttribute(const char* name, const char* *result) { - *result = 0; + if (nsnull != mOwner) + return mOwner->GetAttribute(name, result); + else + { + *result = ""; + return NS_ERROR_FAILURE; + } +} + +NS_IMETHODIMP nsPluginInstancePeerImpl :: SetWindowSize(PRUint32 width, PRUint32 height) +{ +printf("instance peer setwindowsize called\n"); return NS_OK; } -nsresult nsPluginInstancePeerImpl :: Initialize(nsIPluginInstance *aInstance) +nsresult nsPluginInstancePeerImpl :: Initialize(nsIPluginInstanceOwner *aOwner, + const nsMIMEType aMIMEType) { //don't add a ref to precent circular references... MMP - mInstance = aInstance; + mOwner = aOwner; + + aOwner->GetInstance(mInstance); + //release this one too... MMP + NS_IF_RELEASE(mInstance); + + if (nsnull != aMIMEType) + { + mMIMEType = (nsMIMEType)PR_Malloc(PL_strlen(aMIMEType) + 1); + + if (nsnull != mMIMEType) + PL_strcpy((char *)mMIMEType, aMIMEType); + } return NS_OK; } + +nsresult nsPluginInstancePeerImpl :: GetOwner(nsIPluginInstanceOwner *&aOwner) +{ + aOwner = mOwner; + NS_IF_ADDREF(mOwner); + + if (nsnull != mOwner) + return NS_OK; + else + return NS_ERROR_FAILURE; +} diff --git a/mozilla/modules/plugin/nglsrc/nsPluginInstancePeer.h b/mozilla/modules/plugin/nglsrc/nsPluginInstancePeer.h index aed1996112b..4a1d5d310b9 100644 --- a/mozilla/modules/plugin/nglsrc/nsPluginInstancePeer.h +++ b/mozilla/modules/plugin/nglsrc/nsPluginInstancePeer.h @@ -21,6 +21,7 @@ #include "nsIPluginInstancePeer.h" #include "nsIPluginTagInfo.h" +#include "nsIPluginInstanceOwner.h" class nsPluginInstancePeerImpl : public nsIPluginInstancePeer, public nsIPluginTagInfo { @@ -35,9 +36,6 @@ public: NS_IMETHOD GetValue(nsPluginInstancePeerVariable variable, void *value); - NS_IMETHOD - SetValue(nsPluginInstancePeerVariable variable, void *value); - NS_IMETHOD GetMIMEType(nsMIMEType *result); @@ -50,6 +48,9 @@ public: NS_IMETHOD ShowStatus(const char* message); + NS_IMETHOD + SetWindowSize(PRUint32 width, PRUint32 height); + //nsIPluginTagInfo interface NS_IMETHOD @@ -60,10 +61,15 @@ public: //locals - nsresult Initialize(nsIPluginInstance *aInstance); + nsresult Initialize(nsIPluginInstanceOwner *aInstance, + const nsMIMEType aMimeType); + + nsresult GetOwner(nsIPluginInstanceOwner *&aOwner); private: - nsIPluginInstance *mInstance; //we don't add a ref to this + nsIPluginInstance *mInstance; //we don't add a ref to this + nsIPluginInstanceOwner *mOwner; //we don't add a ref to this + nsMIMEType mMIMEType; }; #endif diff --git a/mozilla/modules/plugin/nglsrc/nsPluginStreamPeer.cpp b/mozilla/modules/plugin/nglsrc/nsPluginStreamPeer.cpp index e1f2cd711fe..c99c9c6678a 100644 --- a/mozilla/modules/plugin/nglsrc/nsPluginStreamPeer.cpp +++ b/mozilla/modules/plugin/nglsrc/nsPluginStreamPeer.cpp @@ -23,12 +23,15 @@ nsPluginStreamPeer :: nsPluginStreamPeer() { + NS_INIT_REFCNT(); + mURL = nsnull; mLength = 0; mLastMod = 0; mNotifyData = nsnull; mMIMEType = nsnull; mURLSpec = nsnull; + mReason = nsPluginReason_NoReason; } nsPluginStreamPeer :: ~nsPluginStreamPeer() @@ -122,7 +125,7 @@ NS_IMETHODIMP nsPluginStreamPeer :: GetNotifyData(void* *result) NS_IMETHODIMP nsPluginStreamPeer :: GetReason(nsPluginReason *result) { - *result = nsPluginReason_NoReason; + *result = mReason; return NS_OK; } @@ -157,3 +160,9 @@ nsresult nsPluginStreamPeer :: Initialize(nsIURL *aURL, PRUint32 aLength, return NS_OK; } + +nsresult nsPluginStreamPeer :: SetReason(nsPluginReason aReason) +{ + mReason = aReason; + return NS_OK; +} \ No newline at end of file diff --git a/mozilla/modules/plugin/nglsrc/nsPluginStreamPeer.h b/mozilla/modules/plugin/nglsrc/nsPluginStreamPeer.h index be7822fe88b..fa3967a8c6c 100644 --- a/mozilla/modules/plugin/nglsrc/nsPluginStreamPeer.h +++ b/mozilla/modules/plugin/nglsrc/nsPluginStreamPeer.h @@ -56,13 +56,16 @@ public: PRUint32 aLastMod, nsMIMEType aMIMEType, void *aNotifyData); + nsresult SetReason(nsPluginReason aReason); + private: - nsIURL *mURL; - PRUint32 mLength; - PRUint32 mLastMod; - void *mNotifyData; - nsMIMEType mMIMEType; - char *mURLSpec; + nsIURL *mURL; + PRUint32 mLength; + PRUint32 mLastMod; + void *mNotifyData; + nsMIMEType mMIMEType; + char *mURLSpec; + nsPluginReason mReason; }; #endif