Added support for Start/Stop Applet/Plugin lifetimes.
git-svn-id: svn://10.0.0.236/trunk@30775 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -518,23 +518,23 @@ ns4xPlugin::_write(NPP npp, NPStream *pstream, int32 len, void *buffer)
|
||||
if(!npp)
|
||||
return -1;
|
||||
|
||||
ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata;
|
||||
NS_ASSERTION(wrapper != NULL, "null stream");
|
||||
ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata;
|
||||
NS_ASSERTION(wrapper != NULL, "null stream");
|
||||
|
||||
if (wrapper == NULL)
|
||||
return -1;
|
||||
if (wrapper == NULL)
|
||||
return -1;
|
||||
|
||||
nsIOutputStream* stream;
|
||||
wrapper->GetStream(stream);
|
||||
nsIOutputStream* stream;
|
||||
wrapper->GetStream(stream);
|
||||
|
||||
PRUint32 count = 0;
|
||||
nsresult rv = stream->Write((char *)buffer, len, &count);
|
||||
NS_RELEASE(stream);
|
||||
|
||||
PRUint32 count = 0;
|
||||
nsresult rv = stream->Write((char *)buffer, len, &count);
|
||||
NS_RELEASE(stream);
|
||||
if(rv != NS_OK)
|
||||
return -1;
|
||||
|
||||
if(rv != NS_OK)
|
||||
return -1;
|
||||
|
||||
return (int32)count;
|
||||
return (int32)count;
|
||||
}
|
||||
|
||||
NPError NP_EXPORT
|
||||
@@ -556,17 +556,17 @@ ns4xPlugin::_destroystream(NPP npp, NPStream *pstream, NPError reason)
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata;
|
||||
ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata;
|
||||
|
||||
NS_ASSERTION(wrapper != NULL, "null wrapper");
|
||||
NS_ASSERTION(wrapper != NULL, "null wrapper");
|
||||
|
||||
if (wrapper == NULL)
|
||||
return NPERR_INVALID_PARAM;
|
||||
if (wrapper == NULL)
|
||||
return NPERR_INVALID_PARAM;
|
||||
|
||||
// This will release the wrapped nsIOutputStream.
|
||||
delete wrapper;
|
||||
// This will release the wrapped nsIOutputStream.
|
||||
delete wrapper;
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
void NP_EXPORT
|
||||
@@ -704,27 +704,51 @@ ns4xPlugin::_getvalue(NPP npp, NPNVariable variable, void *result)
|
||||
if(!npp)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata;
|
||||
switch(variable)
|
||||
{
|
||||
#ifdef XP_UNIX
|
||||
case NPNVxDisplay : return NPERR_GENERIC_ERROR;
|
||||
|
||||
NS_ASSERTION(inst != NULL, "null instance");
|
||||
case NPNVxtAppContext : return NPERR_GENERIC_ERROR;
|
||||
#endif
|
||||
|
||||
if (inst == NULL)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
#ifdef XP_PC
|
||||
case NPNVnetscapeWindow : return NPERR_GENERIC_ERROR;
|
||||
#endif
|
||||
|
||||
nsIPluginInstancePeer *peer;
|
||||
case NPNVjavascriptEnabledBool : *(NPBool*)result = TRUE; return NPERR_NO_ERROR;
|
||||
|
||||
if (NS_OK == inst->GetPeer(&peer))
|
||||
{
|
||||
nsresult rv;
|
||||
case NPNVasdEnabledBool : *(NPBool*)result = FALSE; return NPERR_NO_ERROR;
|
||||
|
||||
// XXX Note that for backwards compatibility, the old NPNVariables
|
||||
// map correctly to NPPluginManagerVariables.
|
||||
rv = peer->GetValue((nsPluginInstancePeerVariable)variable, result);
|
||||
NS_RELEASE(peer);
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
return NPERR_GENERIC_ERROR;
|
||||
case NPNVisOfflineBool : *(NPBool*)result = FALSE; return NPERR_NO_ERROR;
|
||||
|
||||
default : return NPERR_GENERIC_ERROR;
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata;
|
||||
|
||||
NS_ASSERTION(inst != NULL, "null instance");
|
||||
|
||||
if (inst == NULL)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
nsIPluginInstancePeer *peer;
|
||||
|
||||
if (NS_OK == inst->GetPeer(&peer))
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// XXX Note that for backwards compatibility, the old NPNVariables
|
||||
// map correctly to NPPluginManagerVariables.
|
||||
rv = peer->GetValue((nsPluginInstancePeerVariable)variable, result);
|
||||
NS_RELEASE(peer);
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
return NPERR_GENERIC_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
NPError NP_EXPORT
|
||||
@@ -818,7 +842,6 @@ ns4xPlugin::_memalloc (uint32 size)
|
||||
java_lang_Class* NP_EXPORT
|
||||
ns4xPlugin::_getJavaClass(void* handle)
|
||||
{
|
||||
// Is this just a generic call into the Java VM?
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -283,6 +283,7 @@ ns4xPluginInstance :: ns4xPluginInstance(NPPluginFuncs* callbacks)
|
||||
|
||||
mWindowless = PR_FALSE;
|
||||
mTransparent = PR_FALSE;
|
||||
mStarted = PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -328,51 +329,7 @@ NS_IMETHODIMP ns4xPluginInstance :: QueryInterface(const nsIID& iid, void** inst
|
||||
|
||||
NS_IMETHODIMP ns4xPluginInstance :: Initialize(nsIPluginInstancePeer* peer)
|
||||
{
|
||||
PRUint16 count = 0;
|
||||
const char* const* names = nsnull;
|
||||
const char* const* values = nsnull;
|
||||
nsresult rv;
|
||||
NPError error;
|
||||
nsIPluginTagInfo* taginfo;
|
||||
|
||||
NS_ASSERTION(peer != NULL, "null peer");
|
||||
|
||||
fPeer = peer;
|
||||
NS_ADDREF(fPeer);
|
||||
|
||||
rv = fPeer->QueryInterface(kIPluginTagInfoIID, (void **)&taginfo);
|
||||
|
||||
if (NS_OK == rv)
|
||||
{
|
||||
taginfo->GetAttributes(count, names, values);
|
||||
NS_IF_RELEASE(taginfo);
|
||||
}
|
||||
|
||||
if (fCallbacks->newp == NULL)
|
||||
return NS_ERROR_FAILURE; // XXX right error?
|
||||
|
||||
// XXX Note that the NPPluginType_* enums were crafted to be
|
||||
// backward compatible...
|
||||
|
||||
nsPluginMode mode;
|
||||
nsMIMEType mimetype;
|
||||
|
||||
fPeer->GetMode(&mode);
|
||||
fPeer->GetMIMEType(&mimetype);
|
||||
|
||||
error = CallNPP_NewProc(fCallbacks->newp,
|
||||
(char *)mimetype,
|
||||
&fNPP,
|
||||
(PRUint16)mode,
|
||||
count,
|
||||
(char**)names,
|
||||
(char**)values,
|
||||
NULL); // saved data
|
||||
|
||||
if(error != NPERR_NO_ERROR)
|
||||
rv = NS_ERROR_FAILURE;
|
||||
|
||||
return rv;
|
||||
return InitializePlugin(peer);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP ns4xPluginInstance :: GetPeer(nsIPluginInstancePeer* *resultingPeer)
|
||||
@@ -385,36 +342,89 @@ NS_IMETHODIMP ns4xPluginInstance :: GetPeer(nsIPluginInstancePeer* *resultingPee
|
||||
|
||||
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");
|
||||
printf("instance start called\n");
|
||||
if(mStarted)
|
||||
return NS_OK;
|
||||
else
|
||||
return InitializePlugin(fPeer);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP ns4xPluginInstance::Stop(void)
|
||||
{
|
||||
printf("instance stop called\n");
|
||||
return NS_OK;
|
||||
NPError error;
|
||||
|
||||
printf("instance stop/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
|
||||
|
||||
mStarted = PR_FALSE;
|
||||
if(error != NPERR_NO_ERROR)
|
||||
return NS_ERROR_FAILURE;
|
||||
else
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult ns4xPluginInstance::InitializePlugin(nsIPluginInstancePeer* peer)
|
||||
{
|
||||
PRUint16 count = 0;
|
||||
const char* const* names = nsnull;
|
||||
const char* const* values = nsnull;
|
||||
nsresult rv;
|
||||
NPError error;
|
||||
nsIPluginTagInfo* taginfo;
|
||||
|
||||
NS_ASSERTION(peer != NULL, "null peer");
|
||||
|
||||
fPeer = peer;
|
||||
NS_ADDREF(fPeer);
|
||||
|
||||
rv = fPeer->QueryInterface(kIPluginTagInfoIID, (void **)&taginfo);
|
||||
|
||||
if (NS_OK == rv)
|
||||
{
|
||||
taginfo->GetAttributes(count, names, values);
|
||||
NS_IF_RELEASE(taginfo);
|
||||
}
|
||||
|
||||
if (fCallbacks->newp == NULL)
|
||||
return NS_ERROR_FAILURE; // XXX right error?
|
||||
|
||||
// XXX Note that the NPPluginType_* enums were crafted to be
|
||||
// backward compatible...
|
||||
|
||||
nsPluginMode mode;
|
||||
nsMIMEType mimetype;
|
||||
|
||||
fPeer->GetMode(&mode);
|
||||
fPeer->GetMIMEType(&mimetype);
|
||||
|
||||
error = CallNPP_NewProc(fCallbacks->newp,
|
||||
(char *)mimetype,
|
||||
&fNPP,
|
||||
(PRUint16)mode,
|
||||
count,
|
||||
(char**)names,
|
||||
(char**)values,
|
||||
NULL); // saved data
|
||||
|
||||
if(error != NPERR_NO_ERROR)
|
||||
rv = NS_ERROR_FAILURE;
|
||||
|
||||
mStarted = PR_TRUE;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP ns4xPluginInstance::Destroy(void)
|
||||
{
|
||||
NPError 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
|
||||
|
||||
if(error != NPERR_NO_ERROR)
|
||||
return NS_ERROR_FAILURE;
|
||||
else
|
||||
return NS_OK;
|
||||
printf("instance destroy called\n");
|
||||
// destruction is handled in the Stop call
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window)
|
||||
|
||||
@@ -112,6 +112,8 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
nsresult InitializePlugin(nsIPluginInstancePeer* peer);
|
||||
|
||||
/**
|
||||
* The plugin instance peer for this instance.
|
||||
*/
|
||||
@@ -135,6 +137,7 @@ protected:
|
||||
|
||||
PRBool mWindowless;
|
||||
PRBool mTransparent;
|
||||
PRBool mStarted;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1002,6 +1002,8 @@ nsPluginHostImpl::nsPluginHostImpl(nsIServiceManager *serviceMgr)
|
||||
NS_INIT_REFCNT();
|
||||
mPluginsLoaded = PR_FALSE;
|
||||
mServiceMgr = serviceMgr;
|
||||
mNumActivePlugins = 0;
|
||||
mOldestActivePlugin = 0;
|
||||
}
|
||||
|
||||
nsPluginHostImpl::~nsPluginHostImpl()
|
||||
@@ -1342,10 +1344,18 @@ NS_IMETHODIMP nsPluginHostImpl::InstantiateEmbededPlugin(const char *aMimeType,
|
||||
nsresult rv;
|
||||
nsIPluginInstance *instance = nsnull;
|
||||
|
||||
if(FindStoppedPluginForURL(aURL, aOwner) == NS_OK)
|
||||
{
|
||||
aOwner->GetInstance(instance);
|
||||
if(!aMimeType || PL_strcasecmp(aMimeType, "application/x-java-vm"))
|
||||
rv = NewEmbededPluginStream(aURL, nsnull, instance);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rv = SetUpPluginInstance(aMimeType, aURL, aOwner);
|
||||
|
||||
|
||||
if(rv == NS_OK)
|
||||
rv = aOwner->GetInstance(instance);
|
||||
rv = aOwner->GetInstance(instance);
|
||||
|
||||
// if we have a failure error, it means we found a plugin for the mimetype,
|
||||
// but we had a problem with the entry point
|
||||
@@ -1378,7 +1388,7 @@ NS_IMETHODIMP nsPluginHostImpl::InstantiateEmbededPlugin(const char *aMimeType,
|
||||
|
||||
// don't make an initial steam if it's a java applet
|
||||
if(!aMimeType || PL_strcasecmp(aMimeType, "application/x-java-vm"))
|
||||
rv = NewEmbededPluginStream(aURL, nsnull, instance);
|
||||
rv = NewEmbededPluginStream(aURL, nsnull, instance);
|
||||
|
||||
NS_RELEASE(instance);
|
||||
}
|
||||
@@ -1403,7 +1413,16 @@ NS_IMETHODIMP nsPluginHostImpl::InstantiateFullPagePlugin(const char *aMimeType,
|
||||
|
||||
if (rv != NS_OK)
|
||||
url = nsnull;
|
||||
|
||||
|
||||
if(FindStoppedPluginForURL(url, aOwner) == NS_OK)
|
||||
{
|
||||
nsIPluginInstance* instance;
|
||||
aOwner->GetInstance(instance);
|
||||
if(!aMimeType || PL_strcasecmp(aMimeType, "application/x-java-vm"))
|
||||
rv = NewFullPagePluginStream(aStreamListener, instance);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rv = SetUpPluginInstance(aMimeType, url, aOwner);
|
||||
|
||||
NS_IF_RELEASE(url);
|
||||
@@ -1433,6 +1452,72 @@ NS_IMETHODIMP nsPluginHostImpl::InstantiateFullPagePlugin(const char *aMimeType,
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsPluginHostImpl::FindStoppedPluginForURL(nsIURL* aURL, nsIPluginInstanceOwner *aOwner)
|
||||
{
|
||||
PRUint32 i;
|
||||
const char* url;
|
||||
(void)aURL->GetSpec(&url);
|
||||
|
||||
for(i=0; i<mNumActivePlugins; i++)
|
||||
{
|
||||
if(!PL_strcmp(url, mActivePluginList[i].mURL))
|
||||
{
|
||||
nsIPluginInstance* instance = mActivePluginList[i].mInstance;
|
||||
nsIPluginInstancePeer* peer;
|
||||
nsPluginWindow *window = nsnull;
|
||||
aOwner->GetWindow(window);
|
||||
|
||||
aOwner->SetInstance(instance);
|
||||
|
||||
// we have to reset the owner and instance in the plugin instance peer
|
||||
//instance->GetPeer(&peer);
|
||||
((nsPluginInstancePeerImpl*)mActivePluginList[i].mPeer)->SetOwner(aOwner);
|
||||
|
||||
aOwner->CreateWidget();
|
||||
instance->SetWindow(window);
|
||||
instance->Start();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
void nsPluginHostImpl::AddInstanceToActiveList(nsIPluginInstance* aInstance, nsIURL* aURL)
|
||||
{
|
||||
const char* url;
|
||||
(void)aURL->GetSpec(&url);
|
||||
|
||||
if(mNumActivePlugins < MAX_ACTIVE_PLUGINS)
|
||||
{
|
||||
mActivePluginList[mNumActivePlugins].mURL = PL_strdup(url);
|
||||
mActivePluginList[mNumActivePlugins].mInstance = aInstance;
|
||||
|
||||
aInstance->GetPeer(&(mActivePluginList[mNumActivePlugins].mPeer));
|
||||
++mNumActivePlugins;
|
||||
}
|
||||
else
|
||||
{
|
||||
// XXX - TODO: we need to make sure that this plugin is currently not active
|
||||
|
||||
// destroy the oldest plugin on the list
|
||||
mActivePluginList[mOldestActivePlugin].mInstance->Destroy();
|
||||
NS_RELEASE(mActivePluginList[mOldestActivePlugin].mInstance);
|
||||
NS_RELEASE(mActivePluginList[mOldestActivePlugin].mPeer);
|
||||
PL_strfree(mActivePluginList[mOldestActivePlugin].mURL);
|
||||
|
||||
// replace it with the new one
|
||||
mActivePluginList[mOldestActivePlugin].mURL = PL_strdup(url);
|
||||
mActivePluginList[mOldestActivePlugin].mInstance = aInstance;
|
||||
aInstance->GetPeer(&(mActivePluginList[mOldestActivePlugin].mPeer));
|
||||
|
||||
++mOldestActivePlugin;
|
||||
if(mOldestActivePlugin == MAX_ACTIVE_PLUGINS)
|
||||
mOldestActivePlugin = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPluginHostImpl::SetUpPluginInstance(const char *aMimeType,
|
||||
nsIURL *aURL,
|
||||
nsIPluginInstanceOwner *aOwner)
|
||||
@@ -1461,10 +1546,12 @@ NS_IMETHODIMP nsPluginHostImpl::SetUpPluginInstance(const char *aMimeType,
|
||||
mimetype = aMimeType;
|
||||
|
||||
|
||||
if (GetPluginFactory(mimetype, &plugin) == NS_OK) {
|
||||
if(GetPluginFactory(mimetype, &plugin) == NS_OK)
|
||||
{
|
||||
// instantiate a plugin.
|
||||
nsIPluginInstance* instance = NULL;
|
||||
if (plugin->CreateInstance(NULL, kIPluginInstanceIID, (void **)&instance) == NS_OK) {
|
||||
if(plugin->CreateInstance(NULL, kIPluginInstanceIID, (void **)&instance) == NS_OK)
|
||||
{
|
||||
aOwner->SetInstance(instance);
|
||||
|
||||
nsPluginInstancePeerImpl *peer = new nsPluginInstancePeerImpl();
|
||||
@@ -1474,10 +1561,12 @@ NS_IMETHODIMP nsPluginHostImpl::SetUpPluginInstance(const char *aMimeType,
|
||||
|
||||
// tell the plugin instance to initialize itself and pass in the peer.
|
||||
instance->Initialize(peer);
|
||||
NS_RELEASE(instance);
|
||||
|
||||
AddInstanceToActiveList(instance, aURL);
|
||||
//NS_RELEASE(instance);
|
||||
result = NS_OK;
|
||||
}
|
||||
NS_RELEASE(plugin);
|
||||
}
|
||||
NS_RELEASE(plugin);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1750,13 +1839,13 @@ NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(const char *aMimeType, nsIPlugi
|
||||
// need to get the plugin factory from this plugin.
|
||||
nsFactoryProc nsGetFactory = nsnull;
|
||||
nsGetFactory = (nsFactoryProc) PR_FindSymbol(pluginTag->mLibrary, "NSGetFactory");
|
||||
if (nsGetFactory != nsnull)
|
||||
if(nsGetFactory != nsnull)
|
||||
{
|
||||
rv = nsGetFactory(mServiceMgr, kPluginCID, nsnull, nsnull, // XXX fix ClassName/ProgID
|
||||
(nsIFactory**)&pluginTag->mEntryPoint);
|
||||
plugin = pluginTag->mEntryPoint;
|
||||
if (plugin != NULL)
|
||||
plugin->Initialize();
|
||||
rv = nsGetFactory(mServiceMgr, kPluginCID, nsnull, nsnull, // XXX fix ClassName/ProgID
|
||||
(nsIFactory**)&pluginTag->mEntryPoint);
|
||||
plugin = pluginTag->mEntryPoint;
|
||||
if (plugin != NULL)
|
||||
plugin->Initialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1764,6 +1853,8 @@ NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(const char *aMimeType, nsIPlugi
|
||||
(nsIPlugin **)&pluginTag->mEntryPoint,
|
||||
mServiceMgr);
|
||||
plugin = pluginTag->mEntryPoint;
|
||||
pluginTag->mFlags |= NS_PLUGIN_FLAG_OLDSCHOOL;
|
||||
|
||||
// no need to initialize, already done by CreatePlugin()
|
||||
}
|
||||
}
|
||||
@@ -1826,57 +1917,6 @@ NS_IMETHODIMP nsPluginHostImpl::LoadPlugins()
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// private methods
|
||||
|
||||
PRLibrary* nsPluginHostImpl::LoadPluginLibrary(const nsFileSpec &pluginSpec)
|
||||
{
|
||||
PRLibrary* plugin = NULL;
|
||||
|
||||
#ifdef XP_PC
|
||||
plugin = PR_LoadLibrary((const char*)pluginSpec);
|
||||
#endif
|
||||
|
||||
#ifdef XP_MAC
|
||||
char* pluginName = pluginSpec.GetLeafName();
|
||||
if (pluginName != NULL) {
|
||||
plugin = PR_LoadLibrary(pluginName);
|
||||
delete[] pluginName;
|
||||
}
|
||||
#endif
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
|
||||
PRLibrary* nsPluginHostImpl::LoadPluginLibrary(const char* pluginPath, const char* path)
|
||||
{
|
||||
#ifdef XP_PC
|
||||
BOOL restoreOrigDir = FALSE;
|
||||
char aOrigDir[MAX_PATH + 1];
|
||||
DWORD dwCheck = ::GetCurrentDirectory(sizeof(aOrigDir), aOrigDir);
|
||||
PR_ASSERT(dwCheck <= MAX_PATH + 1);
|
||||
|
||||
if (dwCheck <= MAX_PATH + 1)
|
||||
{
|
||||
restoreOrigDir = ::SetCurrentDirectory(pluginPath);
|
||||
PR_ASSERT(restoreOrigDir);
|
||||
}
|
||||
|
||||
PRLibrary* plugin = PR_LoadLibrary(path);
|
||||
|
||||
if (restoreOrigDir)
|
||||
{
|
||||
BOOL bCheck = ::SetCurrentDirectory(aOrigDir);
|
||||
PR_ASSERT(bCheck);
|
||||
}
|
||||
|
||||
return plugin;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Called by GetURL and PostURL */
|
||||
|
||||
NS_IMETHODIMP nsPluginHostImpl::NewPluginURLStream(const nsString& aURL,
|
||||
|
||||
@@ -54,6 +54,15 @@ public:
|
||||
PRUint32 mFlags;
|
||||
};
|
||||
|
||||
#define MAX_ACTIVE_PLUGINS 10
|
||||
|
||||
typedef struct nsActivePlugin
|
||||
{
|
||||
char* mURL;
|
||||
nsIPluginInstancePeer* mPeer;
|
||||
nsIPluginInstance* mInstance;
|
||||
} nsActivePlugin;
|
||||
|
||||
#define NS_PLUGIN_FLAG_ENABLED 0x0001 //is this plugin enabled?
|
||||
#define NS_PLUGIN_FLAG_OLDSCHOOL 0x0002 //is this a pre-xpcom plugin?
|
||||
|
||||
@@ -224,17 +233,23 @@ private:
|
||||
nsresult
|
||||
NewFullPagePluginStream(nsIStreamListener *&aStreamListener, nsIPluginInstance *aInstance);
|
||||
|
||||
PRLibrary* LoadPluginLibrary(const nsFileSpec &pluginSpec);
|
||||
|
||||
PRLibrary* LoadPluginLibrary(const char* pluginPath, const char* path);
|
||||
|
||||
nsresult
|
||||
FindPluginEnabledForType(const char* aMimeType, nsPluginTag* &aPlugin);
|
||||
|
||||
nsresult
|
||||
FindStoppedPluginForURL(nsIURL* aURL, nsIPluginInstanceOwner *aOwner);
|
||||
|
||||
void
|
||||
AddInstanceToActiveList(nsIPluginInstance* aInstance, nsIURL* aURL);
|
||||
|
||||
char *mPluginPath;
|
||||
nsPluginTag *mPlugins;
|
||||
PRBool mPluginsLoaded;
|
||||
nsIServiceManager *mServiceMgr;
|
||||
|
||||
PRUint32 mNumActivePlugins;
|
||||
PRUint32 mOldestActivePlugin;
|
||||
nsActivePlugin mActivePluginList[MAX_ACTIVE_PLUGINS];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -827,6 +827,15 @@ nsresult nsPluginInstancePeerImpl::Initialize(nsIPluginInstanceOwner *aOwner,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPluginInstancePeerImpl::SetOwner(nsIPluginInstanceOwner *aOwner)
|
||||
{
|
||||
// do not add refs to these objects to prevent circular references
|
||||
mOwner = aOwner;
|
||||
aOwner->GetInstance(mInstance);
|
||||
NS_IF_RELEASE(mInstance);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPluginInstancePeerImpl::GetOwner(nsIPluginInstanceOwner *&aOwner)
|
||||
{
|
||||
aOwner = mOwner;
|
||||
|
||||
@@ -148,9 +148,11 @@ public:
|
||||
|
||||
//locals
|
||||
|
||||
nsresult Initialize(nsIPluginInstanceOwner *aInstance,
|
||||
nsresult Initialize(nsIPluginInstanceOwner *aOwner,
|
||||
const nsMIMEType aMimeType);
|
||||
|
||||
nsresult SetOwner(nsIPluginInstanceOwner *aOwner);
|
||||
|
||||
nsresult GetOwner(nsIPluginInstanceOwner *&aOwner);
|
||||
|
||||
private:
|
||||
|
||||
@@ -68,6 +68,10 @@ static char* GetKeyValue(char* verbuf, char* key)
|
||||
static PRUint32 CalculateVariantCount(char* mimeTypes)
|
||||
{
|
||||
PRUint32 variants = 1;
|
||||
|
||||
if(mimeTypes == NULL)
|
||||
return 0;
|
||||
|
||||
char* index = mimeTypes;
|
||||
while (*index)
|
||||
{
|
||||
@@ -85,6 +89,9 @@ static char** MakeStringArray(PRUint32 variants, char* data)
|
||||
char* index = data;
|
||||
PRUint32 count = 0;
|
||||
|
||||
if(variants == 0)
|
||||
return NULL;
|
||||
|
||||
buffer = (char **)PR_Malloc(variants * sizeof(char *));
|
||||
if(!buffer)
|
||||
return NULL;
|
||||
|
||||
@@ -518,23 +518,23 @@ ns4xPlugin::_write(NPP npp, NPStream *pstream, int32 len, void *buffer)
|
||||
if(!npp)
|
||||
return -1;
|
||||
|
||||
ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata;
|
||||
NS_ASSERTION(wrapper != NULL, "null stream");
|
||||
ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata;
|
||||
NS_ASSERTION(wrapper != NULL, "null stream");
|
||||
|
||||
if (wrapper == NULL)
|
||||
return -1;
|
||||
if (wrapper == NULL)
|
||||
return -1;
|
||||
|
||||
nsIOutputStream* stream;
|
||||
wrapper->GetStream(stream);
|
||||
nsIOutputStream* stream;
|
||||
wrapper->GetStream(stream);
|
||||
|
||||
PRUint32 count = 0;
|
||||
nsresult rv = stream->Write((char *)buffer, len, &count);
|
||||
NS_RELEASE(stream);
|
||||
|
||||
PRUint32 count = 0;
|
||||
nsresult rv = stream->Write((char *)buffer, len, &count);
|
||||
NS_RELEASE(stream);
|
||||
if(rv != NS_OK)
|
||||
return -1;
|
||||
|
||||
if(rv != NS_OK)
|
||||
return -1;
|
||||
|
||||
return (int32)count;
|
||||
return (int32)count;
|
||||
}
|
||||
|
||||
NPError NP_EXPORT
|
||||
@@ -556,17 +556,17 @@ ns4xPlugin::_destroystream(NPP npp, NPStream *pstream, NPError reason)
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata;
|
||||
ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata;
|
||||
|
||||
NS_ASSERTION(wrapper != NULL, "null wrapper");
|
||||
NS_ASSERTION(wrapper != NULL, "null wrapper");
|
||||
|
||||
if (wrapper == NULL)
|
||||
return NPERR_INVALID_PARAM;
|
||||
if (wrapper == NULL)
|
||||
return NPERR_INVALID_PARAM;
|
||||
|
||||
// This will release the wrapped nsIOutputStream.
|
||||
delete wrapper;
|
||||
// This will release the wrapped nsIOutputStream.
|
||||
delete wrapper;
|
||||
|
||||
return NPERR_NO_ERROR;
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
void NP_EXPORT
|
||||
@@ -704,27 +704,51 @@ ns4xPlugin::_getvalue(NPP npp, NPNVariable variable, void *result)
|
||||
if(!npp)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata;
|
||||
switch(variable)
|
||||
{
|
||||
#ifdef XP_UNIX
|
||||
case NPNVxDisplay : return NPERR_GENERIC_ERROR;
|
||||
|
||||
NS_ASSERTION(inst != NULL, "null instance");
|
||||
case NPNVxtAppContext : return NPERR_GENERIC_ERROR;
|
||||
#endif
|
||||
|
||||
if (inst == NULL)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
#ifdef XP_PC
|
||||
case NPNVnetscapeWindow : return NPERR_GENERIC_ERROR;
|
||||
#endif
|
||||
|
||||
nsIPluginInstancePeer *peer;
|
||||
case NPNVjavascriptEnabledBool : *(NPBool*)result = TRUE; return NPERR_NO_ERROR;
|
||||
|
||||
if (NS_OK == inst->GetPeer(&peer))
|
||||
{
|
||||
nsresult rv;
|
||||
case NPNVasdEnabledBool : *(NPBool*)result = FALSE; return NPERR_NO_ERROR;
|
||||
|
||||
// XXX Note that for backwards compatibility, the old NPNVariables
|
||||
// map correctly to NPPluginManagerVariables.
|
||||
rv = peer->GetValue((nsPluginInstancePeerVariable)variable, result);
|
||||
NS_RELEASE(peer);
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
return NPERR_GENERIC_ERROR;
|
||||
case NPNVisOfflineBool : *(NPBool*)result = FALSE; return NPERR_NO_ERROR;
|
||||
|
||||
default : return NPERR_GENERIC_ERROR;
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata;
|
||||
|
||||
NS_ASSERTION(inst != NULL, "null instance");
|
||||
|
||||
if (inst == NULL)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
|
||||
nsIPluginInstancePeer *peer;
|
||||
|
||||
if (NS_OK == inst->GetPeer(&peer))
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// XXX Note that for backwards compatibility, the old NPNVariables
|
||||
// map correctly to NPPluginManagerVariables.
|
||||
rv = peer->GetValue((nsPluginInstancePeerVariable)variable, result);
|
||||
NS_RELEASE(peer);
|
||||
return rv;
|
||||
}
|
||||
else
|
||||
return NPERR_GENERIC_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
NPError NP_EXPORT
|
||||
@@ -818,7 +842,6 @@ ns4xPlugin::_memalloc (uint32 size)
|
||||
java_lang_Class* NP_EXPORT
|
||||
ns4xPlugin::_getJavaClass(void* handle)
|
||||
{
|
||||
// Is this just a generic call into the Java VM?
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -283,6 +283,7 @@ ns4xPluginInstance :: ns4xPluginInstance(NPPluginFuncs* callbacks)
|
||||
|
||||
mWindowless = PR_FALSE;
|
||||
mTransparent = PR_FALSE;
|
||||
mStarted = PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -328,51 +329,7 @@ NS_IMETHODIMP ns4xPluginInstance :: QueryInterface(const nsIID& iid, void** inst
|
||||
|
||||
NS_IMETHODIMP ns4xPluginInstance :: Initialize(nsIPluginInstancePeer* peer)
|
||||
{
|
||||
PRUint16 count = 0;
|
||||
const char* const* names = nsnull;
|
||||
const char* const* values = nsnull;
|
||||
nsresult rv;
|
||||
NPError error;
|
||||
nsIPluginTagInfo* taginfo;
|
||||
|
||||
NS_ASSERTION(peer != NULL, "null peer");
|
||||
|
||||
fPeer = peer;
|
||||
NS_ADDREF(fPeer);
|
||||
|
||||
rv = fPeer->QueryInterface(kIPluginTagInfoIID, (void **)&taginfo);
|
||||
|
||||
if (NS_OK == rv)
|
||||
{
|
||||
taginfo->GetAttributes(count, names, values);
|
||||
NS_IF_RELEASE(taginfo);
|
||||
}
|
||||
|
||||
if (fCallbacks->newp == NULL)
|
||||
return NS_ERROR_FAILURE; // XXX right error?
|
||||
|
||||
// XXX Note that the NPPluginType_* enums were crafted to be
|
||||
// backward compatible...
|
||||
|
||||
nsPluginMode mode;
|
||||
nsMIMEType mimetype;
|
||||
|
||||
fPeer->GetMode(&mode);
|
||||
fPeer->GetMIMEType(&mimetype);
|
||||
|
||||
error = CallNPP_NewProc(fCallbacks->newp,
|
||||
(char *)mimetype,
|
||||
&fNPP,
|
||||
(PRUint16)mode,
|
||||
count,
|
||||
(char**)names,
|
||||
(char**)values,
|
||||
NULL); // saved data
|
||||
|
||||
if(error != NPERR_NO_ERROR)
|
||||
rv = NS_ERROR_FAILURE;
|
||||
|
||||
return rv;
|
||||
return InitializePlugin(peer);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP ns4xPluginInstance :: GetPeer(nsIPluginInstancePeer* *resultingPeer)
|
||||
@@ -385,36 +342,89 @@ NS_IMETHODIMP ns4xPluginInstance :: GetPeer(nsIPluginInstancePeer* *resultingPee
|
||||
|
||||
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");
|
||||
printf("instance start called\n");
|
||||
if(mStarted)
|
||||
return NS_OK;
|
||||
else
|
||||
return InitializePlugin(fPeer);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP ns4xPluginInstance::Stop(void)
|
||||
{
|
||||
printf("instance stop called\n");
|
||||
return NS_OK;
|
||||
NPError error;
|
||||
|
||||
printf("instance stop/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
|
||||
|
||||
mStarted = PR_FALSE;
|
||||
if(error != NPERR_NO_ERROR)
|
||||
return NS_ERROR_FAILURE;
|
||||
else
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult ns4xPluginInstance::InitializePlugin(nsIPluginInstancePeer* peer)
|
||||
{
|
||||
PRUint16 count = 0;
|
||||
const char* const* names = nsnull;
|
||||
const char* const* values = nsnull;
|
||||
nsresult rv;
|
||||
NPError error;
|
||||
nsIPluginTagInfo* taginfo;
|
||||
|
||||
NS_ASSERTION(peer != NULL, "null peer");
|
||||
|
||||
fPeer = peer;
|
||||
NS_ADDREF(fPeer);
|
||||
|
||||
rv = fPeer->QueryInterface(kIPluginTagInfoIID, (void **)&taginfo);
|
||||
|
||||
if (NS_OK == rv)
|
||||
{
|
||||
taginfo->GetAttributes(count, names, values);
|
||||
NS_IF_RELEASE(taginfo);
|
||||
}
|
||||
|
||||
if (fCallbacks->newp == NULL)
|
||||
return NS_ERROR_FAILURE; // XXX right error?
|
||||
|
||||
// XXX Note that the NPPluginType_* enums were crafted to be
|
||||
// backward compatible...
|
||||
|
||||
nsPluginMode mode;
|
||||
nsMIMEType mimetype;
|
||||
|
||||
fPeer->GetMode(&mode);
|
||||
fPeer->GetMIMEType(&mimetype);
|
||||
|
||||
error = CallNPP_NewProc(fCallbacks->newp,
|
||||
(char *)mimetype,
|
||||
&fNPP,
|
||||
(PRUint16)mode,
|
||||
count,
|
||||
(char**)names,
|
||||
(char**)values,
|
||||
NULL); // saved data
|
||||
|
||||
if(error != NPERR_NO_ERROR)
|
||||
rv = NS_ERROR_FAILURE;
|
||||
|
||||
mStarted = PR_TRUE;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP ns4xPluginInstance::Destroy(void)
|
||||
{
|
||||
NPError 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
|
||||
|
||||
if(error != NPERR_NO_ERROR)
|
||||
return NS_ERROR_FAILURE;
|
||||
else
|
||||
return NS_OK;
|
||||
printf("instance destroy called\n");
|
||||
// destruction is handled in the Stop call
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window)
|
||||
|
||||
@@ -112,6 +112,8 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
nsresult InitializePlugin(nsIPluginInstancePeer* peer);
|
||||
|
||||
/**
|
||||
* The plugin instance peer for this instance.
|
||||
*/
|
||||
@@ -135,6 +137,7 @@ protected:
|
||||
|
||||
PRBool mWindowless;
|
||||
PRBool mTransparent;
|
||||
PRBool mStarted;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1002,6 +1002,8 @@ nsPluginHostImpl::nsPluginHostImpl(nsIServiceManager *serviceMgr)
|
||||
NS_INIT_REFCNT();
|
||||
mPluginsLoaded = PR_FALSE;
|
||||
mServiceMgr = serviceMgr;
|
||||
mNumActivePlugins = 0;
|
||||
mOldestActivePlugin = 0;
|
||||
}
|
||||
|
||||
nsPluginHostImpl::~nsPluginHostImpl()
|
||||
@@ -1342,10 +1344,18 @@ NS_IMETHODIMP nsPluginHostImpl::InstantiateEmbededPlugin(const char *aMimeType,
|
||||
nsresult rv;
|
||||
nsIPluginInstance *instance = nsnull;
|
||||
|
||||
if(FindStoppedPluginForURL(aURL, aOwner) == NS_OK)
|
||||
{
|
||||
aOwner->GetInstance(instance);
|
||||
if(!aMimeType || PL_strcasecmp(aMimeType, "application/x-java-vm"))
|
||||
rv = NewEmbededPluginStream(aURL, nsnull, instance);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rv = SetUpPluginInstance(aMimeType, aURL, aOwner);
|
||||
|
||||
|
||||
if(rv == NS_OK)
|
||||
rv = aOwner->GetInstance(instance);
|
||||
rv = aOwner->GetInstance(instance);
|
||||
|
||||
// if we have a failure error, it means we found a plugin for the mimetype,
|
||||
// but we had a problem with the entry point
|
||||
@@ -1378,7 +1388,7 @@ NS_IMETHODIMP nsPluginHostImpl::InstantiateEmbededPlugin(const char *aMimeType,
|
||||
|
||||
// don't make an initial steam if it's a java applet
|
||||
if(!aMimeType || PL_strcasecmp(aMimeType, "application/x-java-vm"))
|
||||
rv = NewEmbededPluginStream(aURL, nsnull, instance);
|
||||
rv = NewEmbededPluginStream(aURL, nsnull, instance);
|
||||
|
||||
NS_RELEASE(instance);
|
||||
}
|
||||
@@ -1403,7 +1413,16 @@ NS_IMETHODIMP nsPluginHostImpl::InstantiateFullPagePlugin(const char *aMimeType,
|
||||
|
||||
if (rv != NS_OK)
|
||||
url = nsnull;
|
||||
|
||||
|
||||
if(FindStoppedPluginForURL(url, aOwner) == NS_OK)
|
||||
{
|
||||
nsIPluginInstance* instance;
|
||||
aOwner->GetInstance(instance);
|
||||
if(!aMimeType || PL_strcasecmp(aMimeType, "application/x-java-vm"))
|
||||
rv = NewFullPagePluginStream(aStreamListener, instance);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rv = SetUpPluginInstance(aMimeType, url, aOwner);
|
||||
|
||||
NS_IF_RELEASE(url);
|
||||
@@ -1433,6 +1452,72 @@ NS_IMETHODIMP nsPluginHostImpl::InstantiateFullPagePlugin(const char *aMimeType,
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsPluginHostImpl::FindStoppedPluginForURL(nsIURL* aURL, nsIPluginInstanceOwner *aOwner)
|
||||
{
|
||||
PRUint32 i;
|
||||
const char* url;
|
||||
(void)aURL->GetSpec(&url);
|
||||
|
||||
for(i=0; i<mNumActivePlugins; i++)
|
||||
{
|
||||
if(!PL_strcmp(url, mActivePluginList[i].mURL))
|
||||
{
|
||||
nsIPluginInstance* instance = mActivePluginList[i].mInstance;
|
||||
nsIPluginInstancePeer* peer;
|
||||
nsPluginWindow *window = nsnull;
|
||||
aOwner->GetWindow(window);
|
||||
|
||||
aOwner->SetInstance(instance);
|
||||
|
||||
// we have to reset the owner and instance in the plugin instance peer
|
||||
//instance->GetPeer(&peer);
|
||||
((nsPluginInstancePeerImpl*)mActivePluginList[i].mPeer)->SetOwner(aOwner);
|
||||
|
||||
aOwner->CreateWidget();
|
||||
instance->SetWindow(window);
|
||||
instance->Start();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
void nsPluginHostImpl::AddInstanceToActiveList(nsIPluginInstance* aInstance, nsIURL* aURL)
|
||||
{
|
||||
const char* url;
|
||||
(void)aURL->GetSpec(&url);
|
||||
|
||||
if(mNumActivePlugins < MAX_ACTIVE_PLUGINS)
|
||||
{
|
||||
mActivePluginList[mNumActivePlugins].mURL = PL_strdup(url);
|
||||
mActivePluginList[mNumActivePlugins].mInstance = aInstance;
|
||||
|
||||
aInstance->GetPeer(&(mActivePluginList[mNumActivePlugins].mPeer));
|
||||
++mNumActivePlugins;
|
||||
}
|
||||
else
|
||||
{
|
||||
// XXX - TODO: we need to make sure that this plugin is currently not active
|
||||
|
||||
// destroy the oldest plugin on the list
|
||||
mActivePluginList[mOldestActivePlugin].mInstance->Destroy();
|
||||
NS_RELEASE(mActivePluginList[mOldestActivePlugin].mInstance);
|
||||
NS_RELEASE(mActivePluginList[mOldestActivePlugin].mPeer);
|
||||
PL_strfree(mActivePluginList[mOldestActivePlugin].mURL);
|
||||
|
||||
// replace it with the new one
|
||||
mActivePluginList[mOldestActivePlugin].mURL = PL_strdup(url);
|
||||
mActivePluginList[mOldestActivePlugin].mInstance = aInstance;
|
||||
aInstance->GetPeer(&(mActivePluginList[mOldestActivePlugin].mPeer));
|
||||
|
||||
++mOldestActivePlugin;
|
||||
if(mOldestActivePlugin == MAX_ACTIVE_PLUGINS)
|
||||
mOldestActivePlugin = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPluginHostImpl::SetUpPluginInstance(const char *aMimeType,
|
||||
nsIURL *aURL,
|
||||
nsIPluginInstanceOwner *aOwner)
|
||||
@@ -1461,10 +1546,12 @@ NS_IMETHODIMP nsPluginHostImpl::SetUpPluginInstance(const char *aMimeType,
|
||||
mimetype = aMimeType;
|
||||
|
||||
|
||||
if (GetPluginFactory(mimetype, &plugin) == NS_OK) {
|
||||
if(GetPluginFactory(mimetype, &plugin) == NS_OK)
|
||||
{
|
||||
// instantiate a plugin.
|
||||
nsIPluginInstance* instance = NULL;
|
||||
if (plugin->CreateInstance(NULL, kIPluginInstanceIID, (void **)&instance) == NS_OK) {
|
||||
if(plugin->CreateInstance(NULL, kIPluginInstanceIID, (void **)&instance) == NS_OK)
|
||||
{
|
||||
aOwner->SetInstance(instance);
|
||||
|
||||
nsPluginInstancePeerImpl *peer = new nsPluginInstancePeerImpl();
|
||||
@@ -1474,10 +1561,12 @@ NS_IMETHODIMP nsPluginHostImpl::SetUpPluginInstance(const char *aMimeType,
|
||||
|
||||
// tell the plugin instance to initialize itself and pass in the peer.
|
||||
instance->Initialize(peer);
|
||||
NS_RELEASE(instance);
|
||||
|
||||
AddInstanceToActiveList(instance, aURL);
|
||||
//NS_RELEASE(instance);
|
||||
result = NS_OK;
|
||||
}
|
||||
NS_RELEASE(plugin);
|
||||
}
|
||||
NS_RELEASE(plugin);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1750,13 +1839,13 @@ NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(const char *aMimeType, nsIPlugi
|
||||
// need to get the plugin factory from this plugin.
|
||||
nsFactoryProc nsGetFactory = nsnull;
|
||||
nsGetFactory = (nsFactoryProc) PR_FindSymbol(pluginTag->mLibrary, "NSGetFactory");
|
||||
if (nsGetFactory != nsnull)
|
||||
if(nsGetFactory != nsnull)
|
||||
{
|
||||
rv = nsGetFactory(mServiceMgr, kPluginCID, nsnull, nsnull, // XXX fix ClassName/ProgID
|
||||
(nsIFactory**)&pluginTag->mEntryPoint);
|
||||
plugin = pluginTag->mEntryPoint;
|
||||
if (plugin != NULL)
|
||||
plugin->Initialize();
|
||||
rv = nsGetFactory(mServiceMgr, kPluginCID, nsnull, nsnull, // XXX fix ClassName/ProgID
|
||||
(nsIFactory**)&pluginTag->mEntryPoint);
|
||||
plugin = pluginTag->mEntryPoint;
|
||||
if (plugin != NULL)
|
||||
plugin->Initialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1764,6 +1853,8 @@ NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(const char *aMimeType, nsIPlugi
|
||||
(nsIPlugin **)&pluginTag->mEntryPoint,
|
||||
mServiceMgr);
|
||||
plugin = pluginTag->mEntryPoint;
|
||||
pluginTag->mFlags |= NS_PLUGIN_FLAG_OLDSCHOOL;
|
||||
|
||||
// no need to initialize, already done by CreatePlugin()
|
||||
}
|
||||
}
|
||||
@@ -1826,57 +1917,6 @@ NS_IMETHODIMP nsPluginHostImpl::LoadPlugins()
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// private methods
|
||||
|
||||
PRLibrary* nsPluginHostImpl::LoadPluginLibrary(const nsFileSpec &pluginSpec)
|
||||
{
|
||||
PRLibrary* plugin = NULL;
|
||||
|
||||
#ifdef XP_PC
|
||||
plugin = PR_LoadLibrary((const char*)pluginSpec);
|
||||
#endif
|
||||
|
||||
#ifdef XP_MAC
|
||||
char* pluginName = pluginSpec.GetLeafName();
|
||||
if (pluginName != NULL) {
|
||||
plugin = PR_LoadLibrary(pluginName);
|
||||
delete[] pluginName;
|
||||
}
|
||||
#endif
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
|
||||
PRLibrary* nsPluginHostImpl::LoadPluginLibrary(const char* pluginPath, const char* path)
|
||||
{
|
||||
#ifdef XP_PC
|
||||
BOOL restoreOrigDir = FALSE;
|
||||
char aOrigDir[MAX_PATH + 1];
|
||||
DWORD dwCheck = ::GetCurrentDirectory(sizeof(aOrigDir), aOrigDir);
|
||||
PR_ASSERT(dwCheck <= MAX_PATH + 1);
|
||||
|
||||
if (dwCheck <= MAX_PATH + 1)
|
||||
{
|
||||
restoreOrigDir = ::SetCurrentDirectory(pluginPath);
|
||||
PR_ASSERT(restoreOrigDir);
|
||||
}
|
||||
|
||||
PRLibrary* plugin = PR_LoadLibrary(path);
|
||||
|
||||
if (restoreOrigDir)
|
||||
{
|
||||
BOOL bCheck = ::SetCurrentDirectory(aOrigDir);
|
||||
PR_ASSERT(bCheck);
|
||||
}
|
||||
|
||||
return plugin;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Called by GetURL and PostURL */
|
||||
|
||||
NS_IMETHODIMP nsPluginHostImpl::NewPluginURLStream(const nsString& aURL,
|
||||
|
||||
@@ -54,6 +54,15 @@ public:
|
||||
PRUint32 mFlags;
|
||||
};
|
||||
|
||||
#define MAX_ACTIVE_PLUGINS 10
|
||||
|
||||
typedef struct nsActivePlugin
|
||||
{
|
||||
char* mURL;
|
||||
nsIPluginInstancePeer* mPeer;
|
||||
nsIPluginInstance* mInstance;
|
||||
} nsActivePlugin;
|
||||
|
||||
#define NS_PLUGIN_FLAG_ENABLED 0x0001 //is this plugin enabled?
|
||||
#define NS_PLUGIN_FLAG_OLDSCHOOL 0x0002 //is this a pre-xpcom plugin?
|
||||
|
||||
@@ -224,17 +233,23 @@ private:
|
||||
nsresult
|
||||
NewFullPagePluginStream(nsIStreamListener *&aStreamListener, nsIPluginInstance *aInstance);
|
||||
|
||||
PRLibrary* LoadPluginLibrary(const nsFileSpec &pluginSpec);
|
||||
|
||||
PRLibrary* LoadPluginLibrary(const char* pluginPath, const char* path);
|
||||
|
||||
nsresult
|
||||
FindPluginEnabledForType(const char* aMimeType, nsPluginTag* &aPlugin);
|
||||
|
||||
nsresult
|
||||
FindStoppedPluginForURL(nsIURL* aURL, nsIPluginInstanceOwner *aOwner);
|
||||
|
||||
void
|
||||
AddInstanceToActiveList(nsIPluginInstance* aInstance, nsIURL* aURL);
|
||||
|
||||
char *mPluginPath;
|
||||
nsPluginTag *mPlugins;
|
||||
PRBool mPluginsLoaded;
|
||||
nsIServiceManager *mServiceMgr;
|
||||
|
||||
PRUint32 mNumActivePlugins;
|
||||
PRUint32 mOldestActivePlugin;
|
||||
nsActivePlugin mActivePluginList[MAX_ACTIVE_PLUGINS];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -827,6 +827,15 @@ nsresult nsPluginInstancePeerImpl::Initialize(nsIPluginInstanceOwner *aOwner,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPluginInstancePeerImpl::SetOwner(nsIPluginInstanceOwner *aOwner)
|
||||
{
|
||||
// do not add refs to these objects to prevent circular references
|
||||
mOwner = aOwner;
|
||||
aOwner->GetInstance(mInstance);
|
||||
NS_IF_RELEASE(mInstance);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPluginInstancePeerImpl::GetOwner(nsIPluginInstanceOwner *&aOwner)
|
||||
{
|
||||
aOwner = mOwner;
|
||||
|
||||
@@ -148,9 +148,11 @@ public:
|
||||
|
||||
//locals
|
||||
|
||||
nsresult Initialize(nsIPluginInstanceOwner *aInstance,
|
||||
nsresult Initialize(nsIPluginInstanceOwner *aOwner,
|
||||
const nsMIMEType aMimeType);
|
||||
|
||||
nsresult SetOwner(nsIPluginInstanceOwner *aOwner);
|
||||
|
||||
nsresult GetOwner(nsIPluginInstanceOwner *&aOwner);
|
||||
|
||||
private:
|
||||
|
||||
@@ -68,6 +68,10 @@ static char* GetKeyValue(char* verbuf, char* key)
|
||||
static PRUint32 CalculateVariantCount(char* mimeTypes)
|
||||
{
|
||||
PRUint32 variants = 1;
|
||||
|
||||
if(mimeTypes == NULL)
|
||||
return 0;
|
||||
|
||||
char* index = mimeTypes;
|
||||
while (*index)
|
||||
{
|
||||
@@ -85,6 +89,9 @@ static char** MakeStringArray(PRUint32 variants, char* data)
|
||||
char* index = data;
|
||||
PRUint32 count = 0;
|
||||
|
||||
if(variants == 0)
|
||||
return NULL;
|
||||
|
||||
buffer = (char **)PR_Malloc(variants * sizeof(char *));
|
||||
if(!buffer)
|
||||
return NULL;
|
||||
|
||||
Reference in New Issue
Block a user