diff --git a/modules/plugin/base/src/ns4xPlugin.cpp b/modules/plugin/base/src/ns4xPlugin.cpp index 2aba3ae9bb6a..7939ba4b7be2 100644 --- a/modules/plugin/base/src/ns4xPlugin.cpp +++ b/modules/plugin/base/src/ns4xPlugin.cpp @@ -1,995 +1,995 @@ -/* -*- 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. - */ - -// TODO: Implement Java callbacks - -#include "xp_core.h" -#include "nsplugin.h" -#include "ns4xPlugin.h" -#include "ns4xPluginInstance.h" -#include "nsIServiceManager.h" -#include "nsIAllocator.h" -#include "nsIPluginStreamListener.h" -#include "nsPluginsDir.h" - -#ifdef XP_MAC -#include -#endif - -//////////////////////////////////////////////////////////////////////// - -NPNetscapeFuncs ns4xPlugin::CALLBACKS; -nsIPluginManager * ns4xPlugin::mPluginManager; -nsIAllocator * ns4xPlugin::mMalloc; - -void -ns4xPlugin::CheckClassInitialized(void) -{ - static PRBool initialized = FALSE; - - if (initialized) - return; - - mPluginManager = nsnull; - mMalloc = nsnull; - - // XXX It'd be nice to make this const and initialize it - // statically... - CALLBACKS.size = sizeof(CALLBACKS); - CALLBACKS.version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; - -#if !TARGET_CARBON -// pinkerton - these macros rely on BuildRoutineDescriptor(), which is no longer in -// Carbon. Our easy solution to this is to drop support for 68K plugins. Now we just -// need to do the work... - CALLBACKS.geturl = NewNPN_GetURLProc(_geturl); - CALLBACKS.posturl = NewNPN_PostURLProc(_posturl); - CALLBACKS.requestread = NewNPN_RequestReadProc(_requestread); - CALLBACKS.newstream = NewNPN_NewStreamProc(_newstream); - CALLBACKS.write = NewNPN_WriteProc(_write); - CALLBACKS.destroystream = NewNPN_DestroyStreamProc(_destroystream); - CALLBACKS.status = NewNPN_StatusProc(_status); - CALLBACKS.uagent = NewNPN_UserAgentProc(_useragent); - CALLBACKS.memalloc = NewNPN_MemAllocProc(_memalloc); - CALLBACKS.memfree = NewNPN_MemFreeProc(_memfree); - CALLBACKS.memflush = NewNPN_MemFlushProc(_memflush); - CALLBACKS.reloadplugins = NewNPN_ReloadPluginsProc(_reloadplugins); - CALLBACKS.getJavaEnv = NewNPN_GetJavaEnvProc(_getJavaEnv); - CALLBACKS.getJavaPeer = NewNPN_GetJavaPeerProc(_getJavaPeer); - CALLBACKS.geturlnotify = NewNPN_GetURLNotifyProc(_geturlnotify); - CALLBACKS.posturlnotify = NewNPN_PostURLNotifyProc(_posturlnotify); - CALLBACKS.getvalue = NewNPN_GetValueProc(_getvalue); - CALLBACKS.setvalue = NewNPN_SetValueProc(_setvalue); - CALLBACKS.invalidaterect = NewNPN_InvalidateRectProc(_invalidaterect); - CALLBACKS.invalidateregion = NewNPN_InvalidateRegionProc(_invalidateregion); - CALLBACKS.forceredraw = NewNPN_ForceRedrawProc(_forceredraw); -#endif - - initialized = TRUE; -}; - -//////////////////////////////////////////////////////////////////////// -// nsISupports stuff - -NS_IMPL_ADDREF(ns4xPlugin); -NS_IMPL_RELEASE(ns4xPlugin); - -//static NS_DEFINE_IID(kILiveConnectPluginIID, NS_ILIVECONNECTPLUGIN_IID); -static NS_DEFINE_IID(kIPluginIID, NS_IPLUGIN_IID); -static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); -static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); -static NS_DEFINE_IID(kIWindowlessPluginInstancePeerIID, NS_IWINDOWLESSPLUGININSTANCEPEER_IID); -static NS_DEFINE_IID(kPluginManagerCID, NS_PLUGINMANAGER_CID); -static NS_DEFINE_IID(kIPluginManagerIID, NS_IPLUGINMANAGER_IID); -static NS_DEFINE_IID(kAllocatorCID, NS_ALLOCATOR_CID); -static NS_DEFINE_IID(kIAllocatorIID, NS_IALLOCATOR_IID); -static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID); - -//////////////////////////////////////////////////////////////////////// - -ns4xPlugin::ns4xPlugin(NPPluginFuncs* callbacks, NP_PLUGINSHUTDOWN aShutdown, nsIServiceManager* serviceMgr) -{ - NS_INIT_REFCNT(); - - memcpy((void*) &fCallbacks, (void*) callbacks, sizeof(fCallbacks)); - fShutdownEntry = aShutdown; - - // set up the connections to the plugin manager - if (nsnull == mPluginManager) - serviceMgr->GetService(kPluginManagerCID, kIPluginManagerIID, (nsISupports**)&mPluginManager); - - if (nsnull == mMalloc) - serviceMgr->GetService(kAllocatorCID, kIAllocatorIID, (nsISupports**)&mMalloc); -} - - -ns4xPlugin::~ns4xPlugin(void) -{ - -} - - -nsresult -ns4xPlugin::QueryInterface(const nsIID& iid, void** instance) -{ - if (instance == NULL) - return NS_ERROR_NULL_POINTER; - - if (iid.Equals(kIPluginIID)) - { - *instance = (void *)(nsIPlugin *)this; - AddRef(); - return NS_OK; - } - - if (iid.Equals(kIFactoryIID)) - { - *instance = (void *)(nsIFactory *)this; - AddRef(); - return NS_OK; - } - - if (iid.Equals(kISupportsIID)) - { - *instance = (void *)(nsISupports *)this; - AddRef(); - return NS_OK; - } - - return NS_NOINTERFACE; -} - -#ifdef XP_MAC -static char* p2cstrdup(StringPtr pstr) -{ - int len = pstr[0]; - char* cstr = new char[len + 1]; - if (cstr != NULL) { - ::BlockMoveData(pstr + 1, cstr, len); - cstr[len] = '\0'; - } - return cstr; -} - -void -ns4xPlugin::SetPluginRefNum(short aRefNum) -{ - fPluginRefNum = aRefNum; -} -#endif - -//////////////////////////////////////////////////////////////////////// -// Static factory method. -// - -/* - CreatePlugin() - -------------- - Handles the initialization of old, 4x style plugins. Creates the ns4xPlugin object. - One ns4xPlugin object exists per Plugin (not instance). -*/ - -nsresult -ns4xPlugin::CreatePlugin(nsPluginTag* pluginTag, nsIServiceManager* serviceMgr) -{ - CheckClassInitialized(); - printf("debug: edburns ns4xPlugin::CreatePlugin\n"); -#ifdef XP_UNIX - - ns4xPlugin *plptr; - - NPPluginFuncs callbacks; - memset((void*) &callbacks, 0, sizeof(callbacks)); - callbacks.size = sizeof(callbacks); - - printf("debug: edburns ns4xPlugin::CreatePlugin: cleared callbacks\n"); - - NP_PLUGINSHUTDOWN pfnShutdown = - (NP_PLUGINSHUTDOWN)PR_FindSymbol(pluginTag->mLibrary, "NP_Shutdown"); - - // create the new plugin handler - pluginTag->mEntryPoint = plptr = new ns4xPlugin(&callbacks, pfnShutdown, serviceMgr); - - if (pluginTag->mEntryPoint == NULL) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(pluginTag->mEntryPoint); - - // we must init here because the plugin may call NPN functions - // when we call into the NP_Initialize entry point - NPN functions - // require that mBrowserManager be set up - plptr->Initialize(); - - NP_PLUGINUNIXINIT pfnInitialize = - (NP_PLUGINUNIXINIT)PR_FindSymbol(pluginTag->mLibrary, "NP_Initialize"); - - if (pfnInitialize == NULL) - return NS_ERROR_UNEXPECTED; // XXX Right error? - - if (pfnInitialize(&(ns4xPlugin::CALLBACKS),&callbacks) != NS_OK) - return NS_ERROR_UNEXPECTED; - printf("debug: edburns: ns4xPlugin::CreatePlugin: callbacks->newstream: %p\n", - callbacks.newstream); - - // now copy function table back to ns4xPlugin instance - memcpy((void*) &(plptr->fCallbacks), (void*)&callbacks, sizeof(callbacks)); -#endif - -#ifdef XP_PC - // XXX this only applies on Windows - NP_GETENTRYPOINTS pfnGetEntryPoints = - (NP_GETENTRYPOINTS)PR_FindSymbol(pluginTag->mLibrary, "NP_GetEntryPoints"); - - if (pfnGetEntryPoints == NULL) - return NS_ERROR_FAILURE; - - NPPluginFuncs callbacks; - memset((void*) &callbacks, 0, sizeof(callbacks)); - - callbacks.size = sizeof(callbacks); - - if (pfnGetEntryPoints(&callbacks) != NS_OK) - return NS_ERROR_FAILURE; // XXX - -#ifdef XP_PC // XXX This is really XP, but we need to figure out how to do HIBYTE() - if (HIBYTE(callbacks.version) < NP_VERSION_MAJOR) - return NS_ERROR_FAILURE; -#endif - - NP_PLUGINSHUTDOWN pfnShutdown = - (NP_PLUGINSHUTDOWN)PR_FindSymbol(pluginTag->mLibrary, "NP_Shutdown"); - - // create the new plugin handler - pluginTag->mEntryPoint = new ns4xPlugin(&callbacks, pfnShutdown, serviceMgr); - - if (pluginTag->mEntryPoint == NULL) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(pluginTag->mEntryPoint); - - // we must init here because the plugin may call NPN functions - // when we call into the NP_Initialize entry point - NPN functions - // require that mBrowserManager be set up - pluginTag->mEntryPoint->Initialize(); - - // 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, - // I don't want to break the plugins already in the field, so - // we'll accept either name - - NP_PLUGININIT pfnInitialize = - (NP_PLUGININIT)PR_FindSymbol(pluginTag->mLibrary, "NP_Initialize"); - - if (!pfnInitialize) { - pfnInitialize = - (NP_PLUGININIT)PR_FindSymbol(pluginTag->mLibrary, "NP_PluginInit"); - } - - if (pfnInitialize == NULL) - return NS_ERROR_UNEXPECTED; // XXX Right error? - - if (pfnInitialize(&(ns4xPlugin::CALLBACKS)) != NS_OK) - return NS_ERROR_UNEXPECTED; -#endif - -#ifdef XP_MAC - // get the mainRD entry point - NP_MAIN pfnMain = (NP_MAIN) PR_FindSymbol(pluginTag->mLibrary, "mainRD"); - if(pfnMain == NULL) - return NS_ERROR_FAILURE; - - NPP_ShutdownUPP pfnShutdown; - NPPluginFuncs callbacks; - memset((void*) &callbacks, 0, sizeof(callbacks)); - callbacks.size = sizeof(callbacks); - - nsPluginsDir pluginsDir; - if(!pluginsDir.Valid()) - return NS_ERROR_FAILURE; - - short appRefNum = ::CurResFile(); - short pluginRefNum; - for(nsDirectoryIterator iter(pluginsDir); iter.Exists(); iter++) - { - const nsFileSpec& file = iter; - if (pluginsDir.IsPluginFile(file)) - { - FSSpec spec = file; - char* fileName = p2cstrdup(spec.name); - if(!PL_strcmp(fileName, pluginTag->mFileName)) - { - Boolean targetIsFolder, wasAliased; - OSErr err = ::ResolveAliasFile(&spec, true, &targetIsFolder, &wasAliased); - pluginRefNum = ::FSpOpenResFile(&spec, fsRdPerm); - } - } - } - - // call into the entry point - if(CallNPP_MainEntryProc(pfnMain, &(ns4xPlugin::CALLBACKS), &callbacks, &pfnShutdown) != NPERR_NO_ERROR) - return NS_ERROR_FAILURE; - - ::UseResFile(appRefNum); - - if ((callbacks.version >> 8) < NP_VERSION_MAJOR) - return NS_ERROR_FAILURE; - - // create the new plugin handler - ns4xPlugin* plugin = new ns4xPlugin(&callbacks, (NP_PLUGINSHUTDOWN)pfnShutdown, serviceMgr); - - if(plugin == NULL) - return NS_ERROR_OUT_OF_MEMORY; - - plugin->SetPluginRefNum(pluginRefNum); - - pluginTag->mEntryPoint = plugin; - - NS_ADDREF(pluginTag->mEntryPoint); -#endif - -#ifdef XP_UNIX - return NS_ERROR_FAILURE; -#endif - - return NS_OK; -} - -/* - CreateInstance() - ---------------- - Creates a ns4xPluginInstance object. -*/ - -nsresult ns4xPlugin :: CreateInstance(nsISupports *aOuter, - const nsIID &aIID, - void **aResult) -{ - if (aResult == NULL) { - return NS_ERROR_NULL_POINTER; - } - - *aResult = NULL; - - nsISupports *inst; - - inst = nsnull; - inst = (nsISupports *)(nsIPluginInstance *)new ns4xPluginInstance(&fCallbacks); - - if (inst == NULL) { - return NS_ERROR_OUT_OF_MEMORY; - } - - nsresult res = inst->QueryInterface(aIID, aResult); - - if (res != NS_OK) { - // We didn't get the right interface, so clean up - delete inst; - } - - return res; -} - -nsresult ns4xPlugin :: LockFactory(PRBool aLock) -{ - // Not implemented in simplest case. - return NS_OK; -} - -NS_METHOD ns4xPlugin :: CreatePluginInstance(nsISupports *aOuter, REFNSIID aIID, - const char* aPluginMIMEType, - void **aResult) -{ - return CreateInstance(aOuter, aIID, aResult); -} - -nsresult -ns4xPlugin::Initialize(void) -{ - return NS_OK; -} - -nsresult -ns4xPlugin::Shutdown(void) -{ - if (nsnull != fShutdownEntry) - { -#ifdef NS_DEBUG - printf("shutting down plugin %08x\n",(int)this); -#endif -#ifdef XP_MAC - CallNPP_ShutdownProc(fShutdownEntry); - ::CloseResFile(fPluginRefNum); -#else - fShutdownEntry(); -#endif - - fShutdownEntry = nsnull; - } - - NS_IF_RELEASE(mPluginManager); - NS_IF_RELEASE(mMalloc); - - return NS_OK; -} - -nsresult -ns4xPlugin::GetMIMEDescription(const char* *resultingDesc) -{ - printf("plugin getmimedescription called\n"); - *resultingDesc = ""; - return NS_OK; // XXX make a callback, etc. -} - -nsresult -ns4xPlugin::GetValue(nsPluginVariable variable, void *value) -{ -printf("plugin getvalue %d called\n", variable); - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////// -// -// Static callbacks that get routed back through the new C++ API -// - -NPError NP_EXPORT -ns4xPlugin::_geturl(NPP npp, const char* relativeURL, const char* target) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - NS_ASSERTION(mPluginManager != NULL, "null manager"); - - if (inst == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginStreamListener* listener = nsnull; - if(target == nsnull) - inst->NewStream(&listener); - - if(mPluginManager->GetURL(inst, relativeURL, target, listener) != NS_OK) - return NPERR_GENERIC_ERROR; - - return NPERR_NO_ERROR; -} - -NPError NP_EXPORT -ns4xPlugin::_geturlnotify(NPP npp, const char* relativeURL, const char* target, - void* notifyData) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - NS_ASSERTION(mPluginManager != NULL, "null manager"); - - if (inst == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginStreamListener* listener = nsnull; - if(target == nsnull) - ((ns4xPluginInstance*)inst)->NewNotifyStream(&listener, notifyData); - - if(mPluginManager->GetURL(inst, relativeURL, target, listener) != NS_OK) - return NPERR_GENERIC_ERROR; - - return NPERR_NO_ERROR; -} - - -NPError NP_EXPORT -ns4xPlugin::_posturlnotify(NPP npp, const char* relativeURL, const char *target, - uint32 len, const char *buf, NPBool file, - void* notifyData) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - NS_ASSERTION(mPluginManager != NULL, "null manager"); - - if (inst == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginStreamListener* listener = nsnull; - if(target == nsnull) - ((ns4xPluginInstance*)inst)->NewNotifyStream(&listener, notifyData); - - if(mPluginManager->PostURL(inst, relativeURL, len, buf, file, target, listener) != NS_OK) - return NPERR_GENERIC_ERROR; - - return NPERR_NO_ERROR; -} - - -NPError NP_EXPORT -ns4xPlugin::_posturl(NPP npp, const char* relativeURL, const char *target, uint32 len, - const char *buf, NPBool file) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - NS_ASSERTION(mPluginManager != NULL, "null manager"); - - if (inst == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginStreamListener* listener = nsnull; - if(target == nsnull) - inst->NewStream(&listener); - - if(mPluginManager->PostURL(inst, relativeURL, len, buf, file, target, listener) != NS_OK) - return NPERR_GENERIC_ERROR; - - return NPERR_NO_ERROR; -} - -//////////////////////////////////////////////////////////////////////// - -/** - * A little helper class used to wrap up plugin manager streams (that is, - * streams from the plugin to the browser). - */ -class ns4xStreamWrapper -{ -protected: - nsIOutputStream *fStream; - NPStream fNPStream; - -public: - ns4xStreamWrapper(nsIOutputStream* stream); - ~ns4xStreamWrapper(); - - void GetStream(nsIOutputStream* &result); - - NPStream* - GetNPStream(void) { - return &fNPStream; - }; -}; - -ns4xStreamWrapper::ns4xStreamWrapper(nsIOutputStream* stream) - : fStream(stream) -{ - NS_ASSERTION(stream != NULL, "bad stream"); - - fStream = stream; - NS_ADDREF(fStream); - - memset(&fNPStream, 0, sizeof(fNPStream)); - fNPStream.ndata = (void*) this; -} - -ns4xStreamWrapper::~ns4xStreamWrapper(void) -{ - fStream->Close(); - NS_IF_RELEASE(fStream); -} - - -void -ns4xStreamWrapper::GetStream(nsIOutputStream* &result) -{ - result = fStream; - NS_IF_ADDREF(fStream); -} - -//////////////////////////////////////////////////////////////////////// - - -NPError NP_EXPORT -ns4xPlugin::_newstream(NPP npp, NPMIMEType type, const char* window, NPStream* *result) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - - if (inst == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIOutputStream* stream; - nsIPluginInstancePeer *peer; - - if (NS_OK == inst->GetPeer(&peer)) - { - if (peer->NewStream((const char*) type, window, &stream) != NS_OK) - { - NS_RELEASE(peer); - return NPERR_GENERIC_ERROR; - } - - ns4xStreamWrapper* wrapper = new ns4xStreamWrapper(stream); - - if (wrapper == NULL) - { - NS_RELEASE(peer); - NS_RELEASE(stream); - return NPERR_OUT_OF_MEMORY_ERROR; - } - - (*result) = wrapper->GetNPStream(); - - NS_RELEASE(peer); - - return NPERR_NO_ERROR; - } - else - return NPERR_GENERIC_ERROR; -} - -int32 NP_EXPORT -ns4xPlugin::_write(NPP npp, NPStream *pstream, int32 len, void *buffer) -{ - // negative return indicates failure to the plugin - if(!npp) - return -1; - - ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata; - NS_ASSERTION(wrapper != NULL, "null stream"); - - if (wrapper == NULL) - return -1; - - nsIOutputStream* stream; - wrapper->GetStream(stream); - - PRUint32 count = 0; - nsresult rv = stream->Write((char *)buffer, len, &count); - NS_RELEASE(stream); - - if(rv != NS_OK) - return -1; - - return (int32)count; -} - -NPError NP_EXPORT -ns4xPlugin::_destroystream(NPP npp, NPStream *pstream, NPError reason) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - nsISupports* stream = (nsISupports*) pstream->ndata; - nsIPluginStreamListener* listener; - - // DestroyStream can kill two kinds of streams: NPP derived and - // NPN derived. - // check to see if they're trying to kill a NPP stream - if(stream->QueryInterface(kIPluginStreamListenerIID, (void**)&listener) == NS_OK) - { - // XXX we should try to kill this listener here somehow - NS_RELEASE(listener); - return NPERR_NO_ERROR; - } - - ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata; - - NS_ASSERTION(wrapper != NULL, "null wrapper"); - - if (wrapper == NULL) - return NPERR_INVALID_PARAM; - - // This will release the wrapped nsIOutputStream. - delete wrapper; - - return NPERR_NO_ERROR; -} - -void NP_EXPORT -ns4xPlugin::_status(NPP npp, const char *message) -{ - if(!npp) - return; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - - if (inst == NULL) - return; - - nsIPluginInstancePeer *peer; - - if (NS_OK == inst->GetPeer(&peer)) - { - peer->ShowStatus(message); - NS_RELEASE(peer); - } -} - -void NP_EXPORT -ns4xPlugin::_memfree (void *ptr) -{ - if(ptr) - mMalloc->Free(ptr); -} - -uint32 NP_EXPORT -ns4xPlugin::_memflush(uint32 size) -{ - mMalloc->HeapMinimize(); - - return 0; -} - -void NP_EXPORT -ns4xPlugin::_reloadplugins(NPBool reloadPages) -{ - mPluginManager->ReloadPlugins(reloadPages); -} - -void NP_EXPORT -ns4xPlugin::_invalidaterect(NPP npp, NPRect *invalidRect) -{ - if(!npp) - return; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - - if (inst == NULL) - return; - - nsIPluginInstancePeer *peer; - nsIWindowlessPluginInstancePeer *wpeer; - - if (NS_OK == inst->GetPeer(&peer)) - { - if (NS_OK == peer->QueryInterface(kIWindowlessPluginInstancePeerIID, (void **)&wpeer)) - { - // XXX nsRect & NPRect are structurally equivalent - wpeer->InvalidateRect((nsPluginRect *)invalidRect); - NS_RELEASE(wpeer); - } - - NS_RELEASE(peer); - } -} - -void NP_EXPORT -ns4xPlugin::_invalidateregion(NPP npp, NPRegion invalidRegion) -{ - if(!npp) - return; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - - if (inst == NULL) - return; - - nsIPluginInstancePeer *peer; - nsIWindowlessPluginInstancePeer *wpeer; - - if (NS_OK == inst->GetPeer(&peer)) - { - if (NS_OK == peer->QueryInterface(kIWindowlessPluginInstancePeerIID, (void **)&wpeer)) - { - // XXX nsRegion & NPRegion are typedef'd to the same thing - wpeer->InvalidateRegion((nsPluginRegion)invalidRegion); - NS_RELEASE(wpeer); - } - - NS_RELEASE(peer); - } -} - -void NP_EXPORT -ns4xPlugin::_forceredraw(NPP npp) -{ - if(!npp) - return; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - - if (inst == NULL) - return; - - nsIPluginInstancePeer *peer; - nsIWindowlessPluginInstancePeer *wpeer; - - if (NS_OK == inst->GetPeer(&peer)) - { - if (NS_OK == peer->QueryInterface(kIWindowlessPluginInstancePeerIID, (void **)&wpeer)) - { - wpeer->ForceRedraw(); - NS_RELEASE(wpeer); - } - - NS_RELEASE(peer); - } -} - -NPError NP_EXPORT -ns4xPlugin::_getvalue(NPP npp, NPNVariable variable, void *result) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - switch(variable) - { -#ifdef XP_UNIX - case NPNVxDisplay : return NPERR_GENERIC_ERROR; - - case NPNVxtAppContext : return NPERR_GENERIC_ERROR; -#endif - -#ifdef XP_PC - case NPNVnetscapeWindow : return NPERR_GENERIC_ERROR; -#endif - - case NPNVjavascriptEnabledBool : *(NPBool*)result = TRUE; return NPERR_NO_ERROR; - - case NPNVasdEnabledBool : *(NPBool*)result = FALSE; return NPERR_NO_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 -ns4xPlugin::_setvalue(NPP npp, NPPVariable variable, void *result) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - ns4xPluginInstance *inst = (ns4xPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - - if (inst == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - switch (variable) - { - case NPPVpluginWindowBool: - { - NPBool bWindowless = !(*((NPBool *)result)); - return inst->SetWindowless(bWindowless); - } - - case NPPVpluginTransparentBool: - return inst->SetTransparent(*((NPBool *)result)); - - default: - return NPERR_NO_ERROR; - } - -#if 0 - nsIPluginInstancePeer *peer; - - if (NS_OK == inst->GetPeer(&peer)) - { - nsresult rv; - - // XXX Note that for backwards compatibility, the old NPPVariables - // map correctly to NPPluginVariables. - rv = peer->SetValue((nsPluginInstancePeerVariable)variable, result); - NS_RELEASE(peer); - return rv; - } - else - return NS_ERROR_UNEXPECTED; -#endif -} - -NPError NP_EXPORT -ns4xPlugin::_requestread(NPStream *pstream, NPByteRange *rangeList) -{ - return NPERR_STREAM_NOT_SEEKABLE; -} - - -//////////////////////////////////////////////////////////////////////// -// -// On 68K Mac (XXX still supported?), we need to make sure that the -// pointers are in D0 for the following functions that return pointers. -// - -#if defined(XP_MAC) && !defined(powerc) -#pragma pointers_in_D0 -#endif - - -JRIEnv* NP_EXPORT -ns4xPlugin::_getJavaEnv(void) -{ - return NULL; -} - -const char * NP_EXPORT -ns4xPlugin::_useragent(NPP npp) -{ - NS_ASSERTION(mPluginManager != NULL, "null pluginmanager"); - - if (mPluginManager == NULL) - return NULL; - - char *retstr; - - mPluginManager->UserAgent((const char **)&retstr); - - return retstr; -} - -void * NP_EXPORT -ns4xPlugin::_memalloc (uint32 size) -{ - return mMalloc->Alloc(size); -} - -java_lang_Class* NP_EXPORT -ns4xPlugin::_getJavaClass(void* handle) -{ - return NULL; -} - - - -jref NP_EXPORT -ns4xPlugin::_getJavaPeer(NPP npp) -{ - return NULL; -} - - -// eof +/* -*- 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. + */ + +// TODO: Implement Java callbacks + +#include "xp_core.h" +#include "nsplugin.h" +#include "ns4xPlugin.h" +#include "ns4xPluginInstance.h" +#include "nsIServiceManager.h" +#include "nsIAllocator.h" +#include "nsIPluginStreamListener.h" +#include "nsPluginsDir.h" + +#ifdef XP_MAC +#include +#endif + +//////////////////////////////////////////////////////////////////////// + +NPNetscapeFuncs ns4xPlugin::CALLBACKS; +nsIPluginManager * ns4xPlugin::mPluginManager; +nsIAllocator * ns4xPlugin::mMalloc; + +void +ns4xPlugin::CheckClassInitialized(void) +{ + static PRBool initialized = FALSE; + + if (initialized) + return; + + mPluginManager = nsnull; + mMalloc = nsnull; + + // XXX It'd be nice to make this const and initialize it + // statically... + CALLBACKS.size = sizeof(CALLBACKS); + CALLBACKS.version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; + +#if !TARGET_CARBON +// pinkerton - these macros rely on BuildRoutineDescriptor(), which is no longer in +// Carbon. Our easy solution to this is to drop support for 68K plugins. Now we just +// need to do the work... + CALLBACKS.geturl = NewNPN_GetURLProc(_geturl); + CALLBACKS.posturl = NewNPN_PostURLProc(_posturl); + CALLBACKS.requestread = NewNPN_RequestReadProc(_requestread); + CALLBACKS.newstream = NewNPN_NewStreamProc(_newstream); + CALLBACKS.write = NewNPN_WriteProc(_write); + CALLBACKS.destroystream = NewNPN_DestroyStreamProc(_destroystream); + CALLBACKS.status = NewNPN_StatusProc(_status); + CALLBACKS.uagent = NewNPN_UserAgentProc(_useragent); + CALLBACKS.memalloc = NewNPN_MemAllocProc(_memalloc); + CALLBACKS.memfree = NewNPN_MemFreeProc(_memfree); + CALLBACKS.memflush = NewNPN_MemFlushProc(_memflush); + CALLBACKS.reloadplugins = NewNPN_ReloadPluginsProc(_reloadplugins); + CALLBACKS.getJavaEnv = NewNPN_GetJavaEnvProc(_getJavaEnv); + CALLBACKS.getJavaPeer = NewNPN_GetJavaPeerProc(_getJavaPeer); + CALLBACKS.geturlnotify = NewNPN_GetURLNotifyProc(_geturlnotify); + CALLBACKS.posturlnotify = NewNPN_PostURLNotifyProc(_posturlnotify); + CALLBACKS.getvalue = NewNPN_GetValueProc(_getvalue); + CALLBACKS.setvalue = NewNPN_SetValueProc(_setvalue); + CALLBACKS.invalidaterect = NewNPN_InvalidateRectProc(_invalidaterect); + CALLBACKS.invalidateregion = NewNPN_InvalidateRegionProc(_invalidateregion); + CALLBACKS.forceredraw = NewNPN_ForceRedrawProc(_forceredraw); +#endif + + initialized = TRUE; +}; + +//////////////////////////////////////////////////////////////////////// +// nsISupports stuff + +NS_IMPL_ADDREF(ns4xPlugin); +NS_IMPL_RELEASE(ns4xPlugin); + +//static NS_DEFINE_IID(kILiveConnectPluginIID, NS_ILIVECONNECTPLUGIN_IID); +static NS_DEFINE_IID(kIPluginIID, NS_IPLUGIN_IID); +static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +static NS_DEFINE_IID(kIWindowlessPluginInstancePeerIID, NS_IWINDOWLESSPLUGININSTANCEPEER_IID); +static NS_DEFINE_IID(kPluginManagerCID, NS_PLUGINMANAGER_CID); +static NS_DEFINE_IID(kIPluginManagerIID, NS_IPLUGINMANAGER_IID); +static NS_DEFINE_IID(kAllocatorCID, NS_ALLOCATOR_CID); +static NS_DEFINE_IID(kIAllocatorIID, NS_IALLOCATOR_IID); +static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID); + +//////////////////////////////////////////////////////////////////////// + +ns4xPlugin::ns4xPlugin(NPPluginFuncs* callbacks, NP_PLUGINSHUTDOWN aShutdown, nsIServiceManager* serviceMgr) +{ + NS_INIT_REFCNT(); + + memcpy((void*) &fCallbacks, (void*) callbacks, sizeof(fCallbacks)); + fShutdownEntry = aShutdown; + + // set up the connections to the plugin manager + if (nsnull == mPluginManager) + serviceMgr->GetService(kPluginManagerCID, kIPluginManagerIID, (nsISupports**)&mPluginManager); + + if (nsnull == mMalloc) + serviceMgr->GetService(kAllocatorCID, kIAllocatorIID, (nsISupports**)&mMalloc); +} + + +ns4xPlugin::~ns4xPlugin(void) +{ + +} + + +nsresult +ns4xPlugin::QueryInterface(const nsIID& iid, void** instance) +{ + if (instance == NULL) + return NS_ERROR_NULL_POINTER; + + if (iid.Equals(kIPluginIID)) + { + *instance = (void *)(nsIPlugin *)this; + AddRef(); + return NS_OK; + } + + if (iid.Equals(kIFactoryIID)) + { + *instance = (void *)(nsIFactory *)this; + AddRef(); + return NS_OK; + } + + if (iid.Equals(kISupportsIID)) + { + *instance = (void *)(nsISupports *)this; + AddRef(); + return NS_OK; + } + + return NS_NOINTERFACE; +} + +#ifdef XP_MAC +static char* p2cstrdup(StringPtr pstr) +{ + int len = pstr[0]; + char* cstr = new char[len + 1]; + if (cstr != NULL) { + ::BlockMoveData(pstr + 1, cstr, len); + cstr[len] = '\0'; + } + return cstr; +} + +void +ns4xPlugin::SetPluginRefNum(short aRefNum) +{ + fPluginRefNum = aRefNum; +} +#endif + +//////////////////////////////////////////////////////////////////////// +// Static factory method. +// + +/* + CreatePlugin() + -------------- + Handles the initialization of old, 4x style plugins. Creates the ns4xPlugin object. + One ns4xPlugin object exists per Plugin (not instance). +*/ + +nsresult +ns4xPlugin::CreatePlugin(nsPluginTag* pluginTag, nsIServiceManager* serviceMgr) +{ + CheckClassInitialized(); + printf("debug: edburns ns4xPlugin::CreatePlugin\n"); +#ifdef XP_UNIX + + ns4xPlugin *plptr; + + NPPluginFuncs callbacks; + memset((void*) &callbacks, 0, sizeof(callbacks)); + callbacks.size = sizeof(callbacks); + + printf("debug: edburns ns4xPlugin::CreatePlugin: cleared callbacks\n"); + + NP_PLUGINSHUTDOWN pfnShutdown = + (NP_PLUGINSHUTDOWN)PR_FindSymbol(pluginTag->mLibrary, "NP_Shutdown"); + + // create the new plugin handler + pluginTag->mEntryPoint = plptr = new ns4xPlugin(&callbacks, pfnShutdown, serviceMgr); + + if (pluginTag->mEntryPoint == NULL) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(pluginTag->mEntryPoint); + + // we must init here because the plugin may call NPN functions + // when we call into the NP_Initialize entry point - NPN functions + // require that mBrowserManager be set up + plptr->Initialize(); + + NP_PLUGINUNIXINIT pfnInitialize = + (NP_PLUGINUNIXINIT)PR_FindSymbol(pluginTag->mLibrary, "NP_Initialize"); + + if (pfnInitialize == NULL) + return NS_ERROR_UNEXPECTED; // XXX Right error? + + if (pfnInitialize(&(ns4xPlugin::CALLBACKS),&callbacks) != NS_OK) + return NS_ERROR_UNEXPECTED; + printf("debug: edburns: ns4xPlugin::CreatePlugin: callbacks->newstream: %p\n", + callbacks.newstream); + + // now copy function table back to ns4xPlugin instance + memcpy((void*) &(plptr->fCallbacks), (void*)&callbacks, sizeof(callbacks)); +#endif + +#ifdef XP_PC + // XXX this only applies on Windows + NP_GETENTRYPOINTS pfnGetEntryPoints = + (NP_GETENTRYPOINTS)PR_FindSymbol(pluginTag->mLibrary, "NP_GetEntryPoints"); + + if (pfnGetEntryPoints == NULL) + return NS_ERROR_FAILURE; + + NPPluginFuncs callbacks; + memset((void*) &callbacks, 0, sizeof(callbacks)); + + callbacks.size = sizeof(callbacks); + + if (pfnGetEntryPoints(&callbacks) != NS_OK) + return NS_ERROR_FAILURE; // XXX + +#ifdef XP_PC // XXX This is really XP, but we need to figure out how to do HIBYTE() + if (HIBYTE(callbacks.version) < NP_VERSION_MAJOR) + return NS_ERROR_FAILURE; +#endif + + NP_PLUGINSHUTDOWN pfnShutdown = + (NP_PLUGINSHUTDOWN)PR_FindSymbol(pluginTag->mLibrary, "NP_Shutdown"); + + // create the new plugin handler + pluginTag->mEntryPoint = new ns4xPlugin(&callbacks, pfnShutdown, serviceMgr); + + if (pluginTag->mEntryPoint == NULL) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(pluginTag->mEntryPoint); + + // we must init here because the plugin may call NPN functions + // when we call into the NP_Initialize entry point - NPN functions + // require that mBrowserManager be set up + pluginTag->mEntryPoint->Initialize(); + + // 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, + // I don't want to break the plugins already in the field, so + // we'll accept either name + + NP_PLUGININIT pfnInitialize = + (NP_PLUGININIT)PR_FindSymbol(pluginTag->mLibrary, "NP_Initialize"); + + if (!pfnInitialize) { + pfnInitialize = + (NP_PLUGININIT)PR_FindSymbol(pluginTag->mLibrary, "NP_PluginInit"); + } + + if (pfnInitialize == NULL) + return NS_ERROR_UNEXPECTED; // XXX Right error? + + if (pfnInitialize(&(ns4xPlugin::CALLBACKS)) != NS_OK) + return NS_ERROR_UNEXPECTED; +#endif + +#ifdef XP_MAC + // get the mainRD entry point + NP_MAIN pfnMain = (NP_MAIN) PR_FindSymbol(pluginTag->mLibrary, "mainRD"); + if(pfnMain == NULL) + return NS_ERROR_FAILURE; + + NPP_ShutdownUPP pfnShutdown; + NPPluginFuncs callbacks; + memset((void*) &callbacks, 0, sizeof(callbacks)); + callbacks.size = sizeof(callbacks); + + nsPluginsDir pluginsDir; + if(!pluginsDir.Valid()) + return NS_ERROR_FAILURE; + + short appRefNum = ::CurResFile(); + short pluginRefNum; + for(nsDirectoryIterator iter(pluginsDir); iter.Exists(); iter++) + { + const nsFileSpec& file = iter; + if (pluginsDir.IsPluginFile(file)) + { + FSSpec spec = file; + char* fileName = p2cstrdup(spec.name); + if(!PL_strcmp(fileName, pluginTag->mFileName)) + { + Boolean targetIsFolder, wasAliased; + OSErr err = ::ResolveAliasFile(&spec, true, &targetIsFolder, &wasAliased); + pluginRefNum = ::FSpOpenResFile(&spec, fsRdPerm); + } + } + } + + // call into the entry point + if(CallNPP_MainEntryProc(pfnMain, &(ns4xPlugin::CALLBACKS), &callbacks, &pfnShutdown) != NPERR_NO_ERROR) + return NS_ERROR_FAILURE; + + ::UseResFile(appRefNum); + + if ((callbacks.version >> 8) < NP_VERSION_MAJOR) + return NS_ERROR_FAILURE; + + // create the new plugin handler + ns4xPlugin* plugin = new ns4xPlugin(&callbacks, (NP_PLUGINSHUTDOWN)pfnShutdown, serviceMgr); + + if(plugin == NULL) + return NS_ERROR_OUT_OF_MEMORY; + + plugin->SetPluginRefNum(pluginRefNum); + + pluginTag->mEntryPoint = plugin; + + NS_ADDREF(pluginTag->mEntryPoint); +#endif + +#ifdef XP_UNIX + return NS_ERROR_FAILURE; +#endif + + return NS_OK; +} + +/* + CreateInstance() + ---------------- + Creates a ns4xPluginInstance object. +*/ + +nsresult ns4xPlugin :: CreateInstance(nsISupports *aOuter, + const nsIID &aIID, + void **aResult) +{ + if (aResult == NULL) { + return NS_ERROR_NULL_POINTER; + } + + *aResult = NULL; + + nsISupports *inst; + + inst = nsnull; + inst = (nsISupports *)(nsIPluginInstance *)new ns4xPluginInstance(&fCallbacks); + + if (inst == NULL) { + return NS_ERROR_OUT_OF_MEMORY; + } + + nsresult res = inst->QueryInterface(aIID, aResult); + + if (res != NS_OK) { + // We didn't get the right interface, so clean up + delete inst; + } + + return res; +} + +nsresult ns4xPlugin :: LockFactory(PRBool aLock) +{ + // Not implemented in simplest case. + return NS_OK; +} + +NS_METHOD ns4xPlugin :: CreatePluginInstance(nsISupports *aOuter, REFNSIID aIID, + const char* aPluginMIMEType, + void **aResult) +{ + return CreateInstance(aOuter, aIID, aResult); +} + +nsresult +ns4xPlugin::Initialize(void) +{ + return NS_OK; +} + +nsresult +ns4xPlugin::Shutdown(void) +{ + if (nsnull != fShutdownEntry) + { +#ifdef NS_DEBUG + printf("shutting down plugin %08x\n",(int)this); +#endif +#ifdef XP_MAC + CallNPP_ShutdownProc(fShutdownEntry); + ::CloseResFile(fPluginRefNum); +#else + fShutdownEntry(); +#endif + + fShutdownEntry = nsnull; + } + + NS_IF_RELEASE(mPluginManager); + NS_IF_RELEASE(mMalloc); + + return NS_OK; +} + +nsresult +ns4xPlugin::GetMIMEDescription(const char* *resultingDesc) +{ + printf("plugin getmimedescription called\n"); + *resultingDesc = ""; + return NS_OK; // XXX make a callback, etc. +} + +nsresult +ns4xPlugin::GetValue(nsPluginVariable variable, void *value) +{ +printf("plugin getvalue %d called\n", variable); + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////// +// +// Static callbacks that get routed back through the new C++ API +// + +NPError NP_EXPORT +ns4xPlugin::_geturl(NPP npp, const char* relativeURL, const char* target) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + NS_ASSERTION(mPluginManager != NULL, "null manager"); + + if (inst == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginStreamListener* listener = nsnull; + if(target == nsnull) + inst->NewStream(&listener); + + if(mPluginManager->GetURL(inst, relativeURL, target, listener) != NS_OK) + return NPERR_GENERIC_ERROR; + + return NPERR_NO_ERROR; +} + +NPError NP_EXPORT +ns4xPlugin::_geturlnotify(NPP npp, const char* relativeURL, const char* target, + void* notifyData) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + NS_ASSERTION(mPluginManager != NULL, "null manager"); + + if (inst == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginStreamListener* listener = nsnull; + if(target == nsnull) + ((ns4xPluginInstance*)inst)->NewNotifyStream(&listener, notifyData); + + if(mPluginManager->GetURL(inst, relativeURL, target, listener) != NS_OK) + return NPERR_GENERIC_ERROR; + + return NPERR_NO_ERROR; +} + + +NPError NP_EXPORT +ns4xPlugin::_posturlnotify(NPP npp, const char* relativeURL, const char *target, + uint32 len, const char *buf, NPBool file, + void* notifyData) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + NS_ASSERTION(mPluginManager != NULL, "null manager"); + + if (inst == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginStreamListener* listener = nsnull; + if(target == nsnull) + ((ns4xPluginInstance*)inst)->NewNotifyStream(&listener, notifyData); + + if(mPluginManager->PostURL(inst, relativeURL, len, buf, file, target, listener) != NS_OK) + return NPERR_GENERIC_ERROR; + + return NPERR_NO_ERROR; +} + + +NPError NP_EXPORT +ns4xPlugin::_posturl(NPP npp, const char* relativeURL, const char *target, uint32 len, + const char *buf, NPBool file) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + NS_ASSERTION(mPluginManager != NULL, "null manager"); + + if (inst == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginStreamListener* listener = nsnull; + if(target == nsnull) + inst->NewStream(&listener); + + if(mPluginManager->PostURL(inst, relativeURL, len, buf, file, target, listener) != NS_OK) + return NPERR_GENERIC_ERROR; + + return NPERR_NO_ERROR; +} + +//////////////////////////////////////////////////////////////////////// + +/** + * A little helper class used to wrap up plugin manager streams (that is, + * streams from the plugin to the browser). + */ +class ns4xStreamWrapper +{ +protected: + nsIOutputStream *fStream; + NPStream fNPStream; + +public: + ns4xStreamWrapper(nsIOutputStream* stream); + ~ns4xStreamWrapper(); + + void GetStream(nsIOutputStream* &result); + + NPStream* + GetNPStream(void) { + return &fNPStream; + }; +}; + +ns4xStreamWrapper::ns4xStreamWrapper(nsIOutputStream* stream) + : fStream(stream) +{ + NS_ASSERTION(stream != NULL, "bad stream"); + + fStream = stream; + NS_ADDREF(fStream); + + memset(&fNPStream, 0, sizeof(fNPStream)); + fNPStream.ndata = (void*) this; +} + +ns4xStreamWrapper::~ns4xStreamWrapper(void) +{ + fStream->Close(); + NS_IF_RELEASE(fStream); +} + + +void +ns4xStreamWrapper::GetStream(nsIOutputStream* &result) +{ + result = fStream; + NS_IF_ADDREF(fStream); +} + +//////////////////////////////////////////////////////////////////////// + + +NPError NP_EXPORT +ns4xPlugin::_newstream(NPP npp, NPMIMEType type, const char* window, NPStream* *result) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + + if (inst == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIOutputStream* stream; + nsIPluginInstancePeer *peer; + + if (NS_OK == inst->GetPeer(&peer)) + { + if (peer->NewStream((const char*) type, window, &stream) != NS_OK) + { + NS_RELEASE(peer); + return NPERR_GENERIC_ERROR; + } + + ns4xStreamWrapper* wrapper = new ns4xStreamWrapper(stream); + + if (wrapper == NULL) + { + NS_RELEASE(peer); + NS_RELEASE(stream); + return NPERR_OUT_OF_MEMORY_ERROR; + } + + (*result) = wrapper->GetNPStream(); + + NS_RELEASE(peer); + + return NPERR_NO_ERROR; + } + else + return NPERR_GENERIC_ERROR; +} + +int32 NP_EXPORT +ns4xPlugin::_write(NPP npp, NPStream *pstream, int32 len, void *buffer) +{ + // negative return indicates failure to the plugin + if(!npp) + return -1; + + ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata; + NS_ASSERTION(wrapper != NULL, "null stream"); + + if (wrapper == NULL) + return -1; + + nsIOutputStream* stream; + wrapper->GetStream(stream); + + PRUint32 count = 0; + nsresult rv = stream->Write((char *)buffer, len, &count); + NS_RELEASE(stream); + + if(rv != NS_OK) + return -1; + + return (int32)count; +} + +NPError NP_EXPORT +ns4xPlugin::_destroystream(NPP npp, NPStream *pstream, NPError reason) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + nsISupports* stream = (nsISupports*) pstream->ndata; + nsIPluginStreamListener* listener; + + // DestroyStream can kill two kinds of streams: NPP derived and + // NPN derived. + // check to see if they're trying to kill a NPP stream + if(stream->QueryInterface(kIPluginStreamListenerIID, (void**)&listener) == NS_OK) + { + // XXX we should try to kill this listener here somehow + NS_RELEASE(listener); + return NPERR_NO_ERROR; + } + + ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata; + + NS_ASSERTION(wrapper != NULL, "null wrapper"); + + if (wrapper == NULL) + return NPERR_INVALID_PARAM; + + // This will release the wrapped nsIOutputStream. + delete wrapper; + + return NPERR_NO_ERROR; +} + +void NP_EXPORT +ns4xPlugin::_status(NPP npp, const char *message) +{ + if(!npp) + return; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + + if (inst == NULL) + return; + + nsIPluginInstancePeer *peer; + + if (NS_OK == inst->GetPeer(&peer)) + { + peer->ShowStatus(message); + NS_RELEASE(peer); + } +} + +void NP_EXPORT +ns4xPlugin::_memfree (void *ptr) +{ + if(ptr) + mMalloc->Free(ptr); +} + +uint32 NP_EXPORT +ns4xPlugin::_memflush(uint32 size) +{ + mMalloc->HeapMinimize(); + + return 0; +} + +void NP_EXPORT +ns4xPlugin::_reloadplugins(NPBool reloadPages) +{ + mPluginManager->ReloadPlugins(reloadPages); +} + +void NP_EXPORT +ns4xPlugin::_invalidaterect(NPP npp, NPRect *invalidRect) +{ + if(!npp) + return; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + + if (inst == NULL) + return; + + nsIPluginInstancePeer *peer; + nsIWindowlessPluginInstancePeer *wpeer; + + if (NS_OK == inst->GetPeer(&peer)) + { + if (NS_OK == peer->QueryInterface(kIWindowlessPluginInstancePeerIID, (void **)&wpeer)) + { + // XXX nsRect & NPRect are structurally equivalent + wpeer->InvalidateRect((nsPluginRect *)invalidRect); + NS_RELEASE(wpeer); + } + + NS_RELEASE(peer); + } +} + +void NP_EXPORT +ns4xPlugin::_invalidateregion(NPP npp, NPRegion invalidRegion) +{ + if(!npp) + return; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + + if (inst == NULL) + return; + + nsIPluginInstancePeer *peer; + nsIWindowlessPluginInstancePeer *wpeer; + + if (NS_OK == inst->GetPeer(&peer)) + { + if (NS_OK == peer->QueryInterface(kIWindowlessPluginInstancePeerIID, (void **)&wpeer)) + { + // XXX nsRegion & NPRegion are typedef'd to the same thing + wpeer->InvalidateRegion((nsPluginRegion)invalidRegion); + NS_RELEASE(wpeer); + } + + NS_RELEASE(peer); + } +} + +void NP_EXPORT +ns4xPlugin::_forceredraw(NPP npp) +{ + if(!npp) + return; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + + if (inst == NULL) + return; + + nsIPluginInstancePeer *peer; + nsIWindowlessPluginInstancePeer *wpeer; + + if (NS_OK == inst->GetPeer(&peer)) + { + if (NS_OK == peer->QueryInterface(kIWindowlessPluginInstancePeerIID, (void **)&wpeer)) + { + wpeer->ForceRedraw(); + NS_RELEASE(wpeer); + } + + NS_RELEASE(peer); + } +} + +NPError NP_EXPORT +ns4xPlugin::_getvalue(NPP npp, NPNVariable variable, void *result) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + switch(variable) + { +#ifdef XP_UNIX + case NPNVxDisplay : return NPERR_GENERIC_ERROR; + + case NPNVxtAppContext : return NPERR_GENERIC_ERROR; +#endif + +#ifdef XP_PC + case NPNVnetscapeWindow : return NPERR_GENERIC_ERROR; +#endif + + case NPNVjavascriptEnabledBool : *(NPBool*)result = TRUE; return NPERR_NO_ERROR; + + case NPNVasdEnabledBool : *(NPBool*)result = FALSE; return NPERR_NO_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 +ns4xPlugin::_setvalue(NPP npp, NPPVariable variable, void *result) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + ns4xPluginInstance *inst = (ns4xPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + + if (inst == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + switch (variable) + { + case NPPVpluginWindowBool: + { + NPBool bWindowless = !(*((NPBool *)result)); + return inst->SetWindowless(bWindowless); + } + + case NPPVpluginTransparentBool: + return inst->SetTransparent(*((NPBool *)result)); + + default: + return NPERR_NO_ERROR; + } + +#if 0 + nsIPluginInstancePeer *peer; + + if (NS_OK == inst->GetPeer(&peer)) + { + nsresult rv; + + // XXX Note that for backwards compatibility, the old NPPVariables + // map correctly to NPPluginVariables. + rv = peer->SetValue((nsPluginInstancePeerVariable)variable, result); + NS_RELEASE(peer); + return rv; + } + else + return NS_ERROR_UNEXPECTED; +#endif +} + +NPError NP_EXPORT +ns4xPlugin::_requestread(NPStream *pstream, NPByteRange *rangeList) +{ + return NPERR_STREAM_NOT_SEEKABLE; +} + + +//////////////////////////////////////////////////////////////////////// +// +// On 68K Mac (XXX still supported?), we need to make sure that the +// pointers are in D0 for the following functions that return pointers. +// + +#if defined(XP_MAC) && !defined(powerc) +#pragma pointers_in_D0 +#endif + + +JRIEnv* NP_EXPORT +ns4xPlugin::_getJavaEnv(void) +{ + return NULL; +} + +const char * NP_EXPORT +ns4xPlugin::_useragent(NPP npp) +{ + NS_ASSERTION(mPluginManager != NULL, "null pluginmanager"); + + if (mPluginManager == NULL) + return NULL; + + char *retstr; + + mPluginManager->UserAgent((const char **)&retstr); + + return retstr; +} + +void * NP_EXPORT +ns4xPlugin::_memalloc (uint32 size) +{ + return mMalloc->Alloc(size); +} + +java_lang_Class* NP_EXPORT +ns4xPlugin::_getJavaClass(void* handle) +{ + return NULL; +} + + + +jref NP_EXPORT +ns4xPlugin::_getJavaPeer(NPP npp) +{ + return NULL; +} + + +// eof diff --git a/modules/plugin/base/src/ns4xPlugin.h b/modules/plugin/base/src/ns4xPlugin.h index fad9bd1d865d..905521275ca4 100644 --- a/modules/plugin/base/src/ns4xPlugin.h +++ b/modules/plugin/base/src/ns4xPlugin.h @@ -1,249 +1,249 @@ -/* -*- 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 ns4xPlugin_h__ -#define ns4xPlugin_h__ - -#include "nsplugin.h" -#include "prlink.h" // for PRLibrary -#include "npupp.h" -#include "nsPluginHostImpl.h" - -//////////////////////////////////////////////////////////////////////// - -/* - * Use this macro before each exported function - * (between the return address and the function - * itself), to ensure that the function has the - * right calling conventions on Win16. - */ - -#define NP_EXPORT - -//////////////////////////////////////////////////////////////////////// - -// XXX These are defined in platform specific FE directories right now :-/ - -#if defined(XP_PC) || defined(XP_UNIX) || defined(XP_BEOS) -typedef NS_CALLBACK_(NPError, NP_GETENTRYPOINTS) (NPPluginFuncs* pCallbacks); -typedef NS_CALLBACK_(NPError, NP_PLUGININIT) (const NPNetscapeFuncs* pCallbacks); -typedef NS_CALLBACK_(NPError, NP_PLUGINUNIXINIT) (const NPNetscapeFuncs* pCallbacks,NPPluginFuncs* fCallbacks); -typedef NS_CALLBACK_(NPError, NP_PLUGINSHUTDOWN) (void); -#endif - -#ifdef XP_MAC -typedef NS_CALLBACK_(NPError, NP_PLUGINSHUTDOWN) (void); -typedef NS_CALLBACK_(NPError, NP_MAIN) (NPNetscapeFuncs* nCallbacks, NPPluginFuncs* pCallbacks, NPP_ShutdownUPP* unloadUpp); -#endif - -class nsIServiceManager; -class nsIAllocator; - -//////////////////////////////////////////////////////////////////////// - -/** - * A 5.0 wrapper for a 4.x style plugin. - */ - -class ns4xPlugin : public nsIPlugin -{ -public: - - ns4xPlugin(NPPluginFuncs* callbacks, NP_PLUGINSHUTDOWN aShutdown, nsIServiceManager* serviceMgr); - virtual ~ns4xPlugin(void); - - NS_DECL_ISUPPORTS - - //nsIFactory interface - - NS_IMETHOD CreateInstance(nsISupports *aOuter, - REFNSIID aIID, - void **aResult); - - NS_IMETHOD LockFactory(PRBool aLock); - - //nsIPlugin interface - - /** - * Creates a new plugin instance, based on a MIME type. This - * allows different impelementations to be created depending on - * the specified MIME type. - */ - NS_IMETHOD CreatePluginInstance(nsISupports *aOuter, REFNSIID aIID, - const char* aPluginMIMEType, - void **aResult); - - NS_IMETHOD - Initialize(void); - - NS_IMETHOD - Shutdown(void); - - NS_IMETHOD - GetMIMEDescription(const char* *resultingDesc); - - NS_IMETHOD - GetValue(nsPluginVariable variable, void *value); - - //////////////////////////////////////////////////////////////////// - // ns4xPlugin-specific methods - - /** - * A static factory method for constructing 4.x plugins. Constructs - * and initializes an ns4xPlugin object, and returns it in - * result. - */ - - static nsresult - CreatePlugin(nsPluginTag* pluginTag, nsIServiceManager* serviceMgr); - -#ifdef XP_MAC - void - SetPluginRefNum(short aRefNum); -#endif - -protected: - /** - * Ensures that the static CALLBACKS is properly initialized - */ - static void CheckClassInitialized(void); - - //////////////////////////////////////////////////////////////////////// - // Static stub functions that are exported to the 4.x plugin as entry - // points via the CALLBACKS variable. - // - static NPError NP_EXPORT - _requestread(NPStream *pstream, NPByteRange *rangeList); - - static NPError NP_EXPORT - _geturlnotify(NPP npp, const char* relativeURL, const char* target, void* notifyData); - - static NPError NP_EXPORT - _getvalue(NPP npp, NPNVariable variable, void *r_value); - - static NPError NP_EXPORT - _setvalue(NPP npp, NPPVariable variable, void *r_value); - - static NPError NP_EXPORT - _geturl(NPP npp, const char* relativeURL, const char* target); - - static NPError NP_EXPORT - _posturlnotify(NPP npp, const char* relativeURL, const char *target, - uint32 len, const char *buf, NPBool file, void* notifyData); - - static NPError NP_EXPORT - _posturl(NPP npp, const char* relativeURL, const char *target, uint32 len, - const char *buf, NPBool file); - - static NPError NP_EXPORT - _newstream(NPP npp, NPMIMEType type, const char* window, NPStream** pstream); - - static int32 NP_EXPORT - _write(NPP npp, NPStream *pstream, int32 len, void *buffer); - - static NPError NP_EXPORT - _destroystream(NPP npp, NPStream *pstream, NPError reason); - - static void NP_EXPORT - _status(NPP npp, const char *message); - -#if 0 - - static void NP_EXPORT - _registerwindow(NPP npp, void* window); - - static void NP_EXPORT - _unregisterwindow(NPP npp, void* window); - - static int16 NP_EXPORT - _allocateMenuID(NPP npp, NPBool isSubmenu); - -#endif - - static void NP_EXPORT - _memfree (void *ptr); - - static uint32 NP_EXPORT - _memflush(uint32 size); - - static void NP_EXPORT - _reloadplugins(NPBool reloadPages); - - static void NP_EXPORT - _invalidaterect(NPP npp, NPRect *invalidRect); - - static void NP_EXPORT - _invalidateregion(NPP npp, NPRegion invalidRegion); - - static void NP_EXPORT - _forceredraw(NPP npp); - - //////////////////////////////////////////////////////////////////////// - // Anything that returns a pointer needs to be _HERE_ for 68K Mac to - // work. - // - -#if defined(XP_MAC) && !defined(powerc) -#pragma pointers_in_D0 -#endif - - static const char* NP_EXPORT - _useragent(NPP npp); - - static void* NP_EXPORT - _memalloc (uint32 size); - - static JRIEnv* NP_EXPORT - _getJavaEnv(void); - -#if 1 - - static jref NP_EXPORT - _getJavaPeer(NPP npp); - - static java_lang_Class* NP_EXPORT - _getJavaClass(void* handle); - -#endif - -#if defined(XP_MAC) && !defined(powerc) -#pragma pointers_in_A0 -#endif - -#ifdef XP_MAC - short fPluginRefNum; -#endif - - /** - * The plugin-side callbacks that the browser calls. One set of - * plugin callbacks for each plugin. - */ - NPPluginFuncs fCallbacks; - - NP_PLUGINSHUTDOWN fShutdownEntry; - - /** - * The browser-side callbacks that a 4.x-style plugin calls. - */ - static NPNetscapeFuncs CALLBACKS; - - static nsIPluginManager *mPluginManager; - static nsIAllocator *mMalloc; -}; - -#endif // ns4xPlugin_h__ +/* -*- 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 ns4xPlugin_h__ +#define ns4xPlugin_h__ + +#include "nsplugin.h" +#include "prlink.h" // for PRLibrary +#include "npupp.h" +#include "nsPluginHostImpl.h" + +//////////////////////////////////////////////////////////////////////// + +/* + * Use this macro before each exported function + * (between the return address and the function + * itself), to ensure that the function has the + * right calling conventions on Win16. + */ + +#define NP_EXPORT + +//////////////////////////////////////////////////////////////////////// + +// XXX These are defined in platform specific FE directories right now :-/ + +#if defined(XP_PC) || defined(XP_UNIX) || defined(XP_BEOS) +typedef NS_CALLBACK_(NPError, NP_GETENTRYPOINTS) (NPPluginFuncs* pCallbacks); +typedef NS_CALLBACK_(NPError, NP_PLUGININIT) (const NPNetscapeFuncs* pCallbacks); +typedef NS_CALLBACK_(NPError, NP_PLUGINUNIXINIT) (const NPNetscapeFuncs* pCallbacks,NPPluginFuncs* fCallbacks); +typedef NS_CALLBACK_(NPError, NP_PLUGINSHUTDOWN) (void); +#endif + +#ifdef XP_MAC +typedef NS_CALLBACK_(NPError, NP_PLUGINSHUTDOWN) (void); +typedef NS_CALLBACK_(NPError, NP_MAIN) (NPNetscapeFuncs* nCallbacks, NPPluginFuncs* pCallbacks, NPP_ShutdownUPP* unloadUpp); +#endif + +class nsIServiceManager; +class nsIAllocator; + +//////////////////////////////////////////////////////////////////////// + +/** + * A 5.0 wrapper for a 4.x style plugin. + */ + +class ns4xPlugin : public nsIPlugin +{ +public: + + ns4xPlugin(NPPluginFuncs* callbacks, NP_PLUGINSHUTDOWN aShutdown, nsIServiceManager* serviceMgr); + virtual ~ns4xPlugin(void); + + NS_DECL_ISUPPORTS + + //nsIFactory interface + + NS_IMETHOD CreateInstance(nsISupports *aOuter, + REFNSIID aIID, + void **aResult); + + NS_IMETHOD LockFactory(PRBool aLock); + + //nsIPlugin interface + + /** + * Creates a new plugin instance, based on a MIME type. This + * allows different impelementations to be created depending on + * the specified MIME type. + */ + NS_IMETHOD CreatePluginInstance(nsISupports *aOuter, REFNSIID aIID, + const char* aPluginMIMEType, + void **aResult); + + NS_IMETHOD + Initialize(void); + + NS_IMETHOD + Shutdown(void); + + NS_IMETHOD + GetMIMEDescription(const char* *resultingDesc); + + NS_IMETHOD + GetValue(nsPluginVariable variable, void *value); + + //////////////////////////////////////////////////////////////////// + // ns4xPlugin-specific methods + + /** + * A static factory method for constructing 4.x plugins. Constructs + * and initializes an ns4xPlugin object, and returns it in + * result. + */ + + static nsresult + CreatePlugin(nsPluginTag* pluginTag, nsIServiceManager* serviceMgr); + +#ifdef XP_MAC + void + SetPluginRefNum(short aRefNum); +#endif + +protected: + /** + * Ensures that the static CALLBACKS is properly initialized + */ + static void CheckClassInitialized(void); + + //////////////////////////////////////////////////////////////////////// + // Static stub functions that are exported to the 4.x plugin as entry + // points via the CALLBACKS variable. + // + static NPError NP_EXPORT + _requestread(NPStream *pstream, NPByteRange *rangeList); + + static NPError NP_EXPORT + _geturlnotify(NPP npp, const char* relativeURL, const char* target, void* notifyData); + + static NPError NP_EXPORT + _getvalue(NPP npp, NPNVariable variable, void *r_value); + + static NPError NP_EXPORT + _setvalue(NPP npp, NPPVariable variable, void *r_value); + + static NPError NP_EXPORT + _geturl(NPP npp, const char* relativeURL, const char* target); + + static NPError NP_EXPORT + _posturlnotify(NPP npp, const char* relativeURL, const char *target, + uint32 len, const char *buf, NPBool file, void* notifyData); + + static NPError NP_EXPORT + _posturl(NPP npp, const char* relativeURL, const char *target, uint32 len, + const char *buf, NPBool file); + + static NPError NP_EXPORT + _newstream(NPP npp, NPMIMEType type, const char* window, NPStream** pstream); + + static int32 NP_EXPORT + _write(NPP npp, NPStream *pstream, int32 len, void *buffer); + + static NPError NP_EXPORT + _destroystream(NPP npp, NPStream *pstream, NPError reason); + + static void NP_EXPORT + _status(NPP npp, const char *message); + +#if 0 + + static void NP_EXPORT + _registerwindow(NPP npp, void* window); + + static void NP_EXPORT + _unregisterwindow(NPP npp, void* window); + + static int16 NP_EXPORT + _allocateMenuID(NPP npp, NPBool isSubmenu); + +#endif + + static void NP_EXPORT + _memfree (void *ptr); + + static uint32 NP_EXPORT + _memflush(uint32 size); + + static void NP_EXPORT + _reloadplugins(NPBool reloadPages); + + static void NP_EXPORT + _invalidaterect(NPP npp, NPRect *invalidRect); + + static void NP_EXPORT + _invalidateregion(NPP npp, NPRegion invalidRegion); + + static void NP_EXPORT + _forceredraw(NPP npp); + + //////////////////////////////////////////////////////////////////////// + // Anything that returns a pointer needs to be _HERE_ for 68K Mac to + // work. + // + +#if defined(XP_MAC) && !defined(powerc) +#pragma pointers_in_D0 +#endif + + static const char* NP_EXPORT + _useragent(NPP npp); + + static void* NP_EXPORT + _memalloc (uint32 size); + + static JRIEnv* NP_EXPORT + _getJavaEnv(void); + +#if 1 + + static jref NP_EXPORT + _getJavaPeer(NPP npp); + + static java_lang_Class* NP_EXPORT + _getJavaClass(void* handle); + +#endif + +#if defined(XP_MAC) && !defined(powerc) +#pragma pointers_in_A0 +#endif + +#ifdef XP_MAC + short fPluginRefNum; +#endif + + /** + * The plugin-side callbacks that the browser calls. One set of + * plugin callbacks for each plugin. + */ + NPPluginFuncs fCallbacks; + + NP_PLUGINSHUTDOWN fShutdownEntry; + + /** + * The browser-side callbacks that a 4.x-style plugin calls. + */ + static NPNetscapeFuncs CALLBACKS; + + static nsIPluginManager *mPluginManager; + static nsIAllocator *mMalloc; +}; + +#endif // ns4xPlugin_h__ diff --git a/modules/plugin/base/src/ns4xPluginInstance.cpp b/modules/plugin/base/src/ns4xPluginInstance.cpp index 7343344933f3..1791907846b4 100644 --- a/modules/plugin/base/src/ns4xPluginInstance.cpp +++ b/modules/plugin/base/src/ns4xPluginInstance.cpp @@ -1,617 +1,617 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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. - */ - -#include "ns4xPluginInstance.h" -#include "nsIPluginStreamListener.h" - -#include "prlog.h" -#include "prmem.h" -#include "nscore.h" - - -class ns4xPluginStreamListener : public nsIPluginStreamListener { - -public: - - NS_DECL_ISUPPORTS - - //////////////////////////////////////////////////////////////////////////// - // from nsIPluginStreamListener: - - NS_IMETHOD - OnStartBinding(nsIPluginStreamInfo* pluginInfo); - - NS_IMETHOD - OnDataAvailable(nsIPluginStreamInfo* pluginInfo, nsIInputStream* input, PRUint32 length); - - NS_IMETHOD - OnFileAvailable( nsIPluginStreamInfo* pluginInfo, const char* fileName); - - NS_IMETHOD - OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status); - - NS_IMETHOD - GetStreamType(nsPluginStreamType *result); - - //////////////////////////////////////////////////////////////////////////// - // ns4xPluginStreamListener specific methods: - - ns4xPluginStreamListener(nsIPluginInstance* inst, void* notifyData); - virtual ~ns4xPluginStreamListener(void); - -protected: - - void* mNotifyData; - ns4xPluginInstance* mInst; - NPStream mNPStream; - PRUint32 mPosition; - nsPluginStreamType mStreamType; -}; - - -//////////////////////////////////////////////////////////////////////////////// -// ns4xPluginStreamListener Methods -//////////////////////////////////////////////////////////////////////////////// - -static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID); - -ns4xPluginStreamListener::ns4xPluginStreamListener(nsIPluginInstance* inst, void* notifyData) - : mNotifyData(notifyData) -{ - NS_INIT_REFCNT(); - mInst = (ns4xPluginInstance*) inst; - mPosition = 0; - - // Initialize the 4.x interface structure - memset(&mNPStream, 0, sizeof(mNPStream)); - - NS_IF_ADDREF(mInst); -} - -ns4xPluginStreamListener::~ns4xPluginStreamListener(void) -{ - NS_IF_RELEASE(mInst); -} - -NS_IMPL_ISUPPORTS(ns4xPluginStreamListener, kIPluginStreamListenerIID); - -NS_IMETHODIMP -ns4xPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo) -{ - - printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding()\n"); - NPP npp; - const NPPluginFuncs *callbacks; - PRBool seekable; - nsMIMEType contentType; - PRUint16 streamType = NP_NORMAL; - NPError error; - - mNPStream.ndata = (void*) this; - pluginInfo->GetURL(&mNPStream.url); - mNPStream.notifyData = mNotifyData; - - pluginInfo->GetLength((PRUint32*)&(mNPStream.end)); - pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified)); - pluginInfo->IsSeekable(&seekable); - pluginInfo->GetContentType(&contentType); - - mInst->GetCallbacks(&callbacks); - mInst->GetNPP(&npp); - - printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding() done GetNPP()\n"); -#if !TARGET_CARBON - printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding() about to call CallNPP_NewStreamProc: callbacks->newstream: %p\n", callbacks->newstream); -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - error = CallNPP_NewStreamProc(callbacks->newstream, - npp, - (char *)contentType, - &mNPStream, - seekable, - &streamType); - if(error != NPERR_NO_ERROR) - return NS_ERROR_FAILURE; -#endif - // translate the old 4x style stream type to the new one - switch(streamType) - { - case NP_NORMAL : mStreamType = nsPluginStreamType_Normal; break; - - case NP_ASFILEONLY : mStreamType = nsPluginStreamType_AsFileOnly; break; - - case NP_ASFILE : mStreamType = nsPluginStreamType_AsFile; break; - - case NP_SEEK : mStreamType = nsPluginStreamType_Seek; break; - - default: return NS_ERROR_FAILURE; - } - - printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding() done switch\n"); - - return NS_OK; -} - -NS_IMETHODIMP -ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo, - nsIInputStream* input, - PRUint32 length) -{ - const NPPluginFuncs *callbacks; - NPP npp; - PRUint32 numtowrite = 0; - PRUint32 amountRead = 0; - PRInt32 writeCount = 0; - - pluginInfo->GetURL(&mNPStream.url); - pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified)); - - mInst->GetCallbacks(&callbacks); - mInst->GetNPP(&npp); - - if (callbacks->write == NULL || length == 0) - return NS_OK; // XXX ? - - // Get the data from the input stream - char* buffer = (char*) PR_Malloc(length); - if (buffer) - input->Read(buffer, length, &amountRead); - - // amountRead tells us how many bytes were put in the buffer - // WriteReady returns to us how many bytes the plugin is - // ready to handle - we have to keep calling WriteReady and - // Write until the buffer is empty - while (amountRead > 0) - { - if (callbacks->writeready != NULL) - { -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - numtowrite = CallNPP_WriteReadyProc(callbacks->writeready, - npp, - &mNPStream); -#endif - - if (numtowrite > amountRead) - numtowrite = amountRead; - } - else // if WriteReady is not supported by the plugin, just write the whole buffer - numtowrite = length; - - // if WriteReady returned 0, the plugin is not ready to handle the data, - // so just skip the Write until WriteReady returns a >0 value - if(numtowrite > 0) - { -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - writeCount = CallNPP_WriteProc(callbacks->write, - npp, - &mNPStream, - mPosition, - numtowrite, - (void *)buffer); - if(writeCount < 0) - return NS_ERROR_FAILURE; -#endif - amountRead -= numtowrite; - mPosition += numtowrite; - } - } - - return NS_OK; -} - -NS_IMETHODIMP -ns4xPluginStreamListener::OnFileAvailable(nsIPluginStreamInfo* pluginInfo, const char* fileName) -{ - const NPPluginFuncs *callbacks; - NPP npp; - - pluginInfo->GetURL(&mNPStream.url); - - mInst->GetCallbacks(&callbacks); - mInst->GetNPP(&npp); - - if (callbacks->asfile == NULL) - return NS_OK; - -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - CallNPP_StreamAsFileProc(callbacks->asfile, - npp, - &mNPStream, - fileName); -#endif - - return NS_OK; -} - -NS_IMETHODIMP -ns4xPluginStreamListener::OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status) -{ - const NPPluginFuncs *callbacks; - NPP npp; - NPError error; - - pluginInfo->GetURL(&mNPStream.url); - pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified)); - - mInst->GetCallbacks(&callbacks); - mInst->GetNPP(&npp); - - if (callbacks->destroystream != NULL) - { - // XXX need to convert status to NPReason -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - error = CallNPP_DestroyStreamProc(callbacks->destroystream, - npp, - &mNPStream, - NPRES_DONE); - if(error != NPERR_NO_ERROR) - return NS_ERROR_FAILURE; -#endif - } - - // check to see if we have a call back - if (callbacks->urlnotify != NULL && mNotifyData != nsnull) - { -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - CallNPP_URLNotifyProc(callbacks->urlnotify, - npp, - mNPStream.url, - nsPluginReason_Done, - mNotifyData); -#endif - } - - return NS_OK; -} - -NS_IMETHODIMP -ns4xPluginStreamListener::GetStreamType(nsPluginStreamType *result) -{ - *result = mStreamType; - return NS_OK; -} - -ns4xPluginInstance :: ns4xPluginInstance(NPPluginFuncs* callbacks) - : fCallbacks(callbacks) -{ - NS_INIT_REFCNT(); - - NS_ASSERTION(fCallbacks != NULL, "null callbacks"); - - // Initialize the NPP structure. - - fNPP.pdata = NULL; - fNPP.ndata = this; - - fPeer = nsnull; - - mWindowless = PR_FALSE; - mTransparent = PR_FALSE; - mStarted = PR_FALSE; -} - - -ns4xPluginInstance :: ~ns4xPluginInstance(void) -{ - NS_RELEASE(fPeer); -} - - -//////////////////////////////////////////////////////////////////////// - -NS_IMPL_ADDREF(ns4xPluginInstance); -NS_IMPL_RELEASE(ns4xPluginInstance); - -static NS_DEFINE_IID(kIPluginInstanceIID, NS_IPLUGININSTANCE_IID); -static NS_DEFINE_IID(kIPluginTagInfoIID, NS_IPLUGINTAGINFO_IID); -static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); - -NS_IMETHODIMP ns4xPluginInstance :: QueryInterface(const nsIID& iid, void** instance) -{ - if (instance == NULL) - return NS_ERROR_NULL_POINTER; - - if (iid.Equals(kIPluginInstanceIID)) - { - *instance = (void *)(nsIPluginInstance *)this; - AddRef(); - return NS_OK; - } - - if (iid.Equals(kISupportsIID)) - { - *instance = (void *)(nsISupports *)this; - AddRef(); - return NS_OK; - } - - return NS_NOINTERFACE; -} - - -//////////////////////////////////////////////////////////////////////// - -NS_IMETHODIMP ns4xPluginInstance :: Initialize(nsIPluginInstancePeer* peer) -{ - return InitializePlugin(peer); -} - -NS_IMETHODIMP ns4xPluginInstance :: GetPeer(nsIPluginInstancePeer* *resultingPeer) -{ - NS_ADDREF(fPeer); - *resultingPeer = fPeer; - - return NS_OK; -} - -NS_IMETHODIMP ns4xPluginInstance::Start(void) -{ - printf("instance start called\n"); - if(mStarted) - return NS_OK; - else - return InitializePlugin(fPeer); -} - -NS_IMETHODIMP ns4xPluginInstance::Stop(void) -{ - NPError error; - - printf("instance stop/destroy called\n"); - if (fCallbacks->destroy == NULL) - return NS_ERROR_FAILURE; // XXX right error? - - NPSavedData *sdata; - -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - error = (nsresult)CallNPP_DestroyProc(fCallbacks->destroy, - &fNPP, &sdata); // saved data -#endif - - 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); - -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - error = CallNPP_NewProc(fCallbacks->newp, - (char *)mimetype, - &fNPP, - (PRUint16)mode, - count, - (char**)names, - (char**)values, - NULL); // saved data -#endif - - if(error != NPERR_NO_ERROR) - rv = NS_ERROR_FAILURE; - - mStarted = PR_TRUE; - - return rv; -} - -NS_IMETHODIMP ns4xPluginInstance::Destroy(void) -{ - printf("instance destroy called\n"); - // destruction is handled in the Stop call - return NS_OK; -} - -NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window) -{ - // XXX 4.x plugins don't want a SetWindow(NULL). - - if (window == NULL || mStarted == PR_FALSE) - return NS_OK; - - NPError error; - - if (fCallbacks->setwindow) - { - // XXX Turns out that NPPluginWindow and NPWindow are structurally - // identical (on purpose!), so there's no need to make a copy. - -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - error = CallNPP_SetWindowProc(fCallbacks->setwindow, - &fNPP, - (NPWindow*) window); -#endif - - // XXX In the old code, we'd just ignore any errors coming - // back from the plugin's SetWindow(). Is this the correct - // behavior?!? - - if (error != NPERR_NO_ERROR) - printf("error in setwindow %d\n", error); - } - - return NS_OK; -} - -/* NOTE: the caller must free the stream listener */ - -NS_IMETHODIMP ns4xPluginInstance::NewStream(nsIPluginStreamListener** listener) -{ - nsISupports* stream = nsnull; - stream = (nsISupports *)(nsIPluginStreamListener *)new ns4xPluginStreamListener(this, nsnull); - - if(stream == nsnull) - return NS_ERROR_OUT_OF_MEMORY; - - nsresult res = stream->QueryInterface(kIPluginStreamListenerIID, (void**)listener); - - // If we didn't get the right interface, clean up - if (res != NS_OK) - delete stream; - - return res; -} - -nsresult ns4xPluginInstance::NewNotifyStream(nsIPluginStreamListener** listener, void* notifyData) -{ - *listener = new ns4xPluginStreamListener(this, notifyData); - return NS_OK; -} - -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"); - PRInt16 res = 0; - - if (fCallbacks->event) - { -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. -#ifdef XP_MAC - res = CallNPP_HandleEventProc(fCallbacks->event, - &fNPP, - (void*) event->event); -#endif - -#ifdef XP_WIN //~~~ - NPEvent npEvent; - npEvent.event = event->event; - npEvent.wParam = event->wParam; - npEvent.lParam = event->lParam; - res = CallNPP_HandleEventProc(fCallbacks->event, - &fNPP, - (void*)&npEvent); -#endif - -#endif - - *handled = res; - } - - - return NS_OK; -} - -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; -} - -nsresult ns4xPluginInstance::GetNPP(NPP* aNPP) -{ - if(aNPP != nsnull) - *aNPP = &fNPP; - else - return NS_ERROR_NULL_POINTER; - - return NS_OK; -} - -nsresult ns4xPluginInstance::GetCallbacks(const NPPluginFuncs ** aCallbacks) -{ - if(aCallbacks != nsnull) - *aCallbacks = fCallbacks; - else - return NS_ERROR_NULL_POINTER; - - return NS_OK; -} - -nsresult ns4xPluginInstance :: SetWindowless(PRBool aWindowless) -{ - mWindowless = aWindowless; - return NS_OK; -} - -nsresult ns4xPluginInstance :: SetTransparent(PRBool aTransparent) -{ - mTransparent = aTransparent; - return NS_OK; -} +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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. + */ + +#include "ns4xPluginInstance.h" +#include "nsIPluginStreamListener.h" + +#include "prlog.h" +#include "prmem.h" +#include "nscore.h" + + +class ns4xPluginStreamListener : public nsIPluginStreamListener { + +public: + + NS_DECL_ISUPPORTS + + //////////////////////////////////////////////////////////////////////////// + // from nsIPluginStreamListener: + + NS_IMETHOD + OnStartBinding(nsIPluginStreamInfo* pluginInfo); + + NS_IMETHOD + OnDataAvailable(nsIPluginStreamInfo* pluginInfo, nsIInputStream* input, PRUint32 length); + + NS_IMETHOD + OnFileAvailable( nsIPluginStreamInfo* pluginInfo, const char* fileName); + + NS_IMETHOD + OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status); + + NS_IMETHOD + GetStreamType(nsPluginStreamType *result); + + //////////////////////////////////////////////////////////////////////////// + // ns4xPluginStreamListener specific methods: + + ns4xPluginStreamListener(nsIPluginInstance* inst, void* notifyData); + virtual ~ns4xPluginStreamListener(void); + +protected: + + void* mNotifyData; + ns4xPluginInstance* mInst; + NPStream mNPStream; + PRUint32 mPosition; + nsPluginStreamType mStreamType; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// ns4xPluginStreamListener Methods +//////////////////////////////////////////////////////////////////////////////// + +static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID); + +ns4xPluginStreamListener::ns4xPluginStreamListener(nsIPluginInstance* inst, void* notifyData) + : mNotifyData(notifyData) +{ + NS_INIT_REFCNT(); + mInst = (ns4xPluginInstance*) inst; + mPosition = 0; + + // Initialize the 4.x interface structure + memset(&mNPStream, 0, sizeof(mNPStream)); + + NS_IF_ADDREF(mInst); +} + +ns4xPluginStreamListener::~ns4xPluginStreamListener(void) +{ + NS_IF_RELEASE(mInst); +} + +NS_IMPL_ISUPPORTS(ns4xPluginStreamListener, kIPluginStreamListenerIID); + +NS_IMETHODIMP +ns4xPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo) +{ + + printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding()\n"); + NPP npp; + const NPPluginFuncs *callbacks; + PRBool seekable; + nsMIMEType contentType; + PRUint16 streamType = NP_NORMAL; + NPError error; + + mNPStream.ndata = (void*) this; + pluginInfo->GetURL(&mNPStream.url); + mNPStream.notifyData = mNotifyData; + + pluginInfo->GetLength((PRUint32*)&(mNPStream.end)); + pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified)); + pluginInfo->IsSeekable(&seekable); + pluginInfo->GetContentType(&contentType); + + mInst->GetCallbacks(&callbacks); + mInst->GetNPP(&npp); + + printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding() done GetNPP()\n"); +#if !TARGET_CARBON + printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding() about to call CallNPP_NewStreamProc: callbacks->newstream: %p\n", callbacks->newstream); +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + error = CallNPP_NewStreamProc(callbacks->newstream, + npp, + (char *)contentType, + &mNPStream, + seekable, + &streamType); + if(error != NPERR_NO_ERROR) + return NS_ERROR_FAILURE; +#endif + // translate the old 4x style stream type to the new one + switch(streamType) + { + case NP_NORMAL : mStreamType = nsPluginStreamType_Normal; break; + + case NP_ASFILEONLY : mStreamType = nsPluginStreamType_AsFileOnly; break; + + case NP_ASFILE : mStreamType = nsPluginStreamType_AsFile; break; + + case NP_SEEK : mStreamType = nsPluginStreamType_Seek; break; + + default: return NS_ERROR_FAILURE; + } + + printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding() done switch\n"); + + return NS_OK; +} + +NS_IMETHODIMP +ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo, + nsIInputStream* input, + PRUint32 length) +{ + const NPPluginFuncs *callbacks; + NPP npp; + PRUint32 numtowrite = 0; + PRUint32 amountRead = 0; + PRInt32 writeCount = 0; + + pluginInfo->GetURL(&mNPStream.url); + pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified)); + + mInst->GetCallbacks(&callbacks); + mInst->GetNPP(&npp); + + if (callbacks->write == NULL || length == 0) + return NS_OK; // XXX ? + + // Get the data from the input stream + char* buffer = (char*) PR_Malloc(length); + if (buffer) + input->Read(buffer, length, &amountRead); + + // amountRead tells us how many bytes were put in the buffer + // WriteReady returns to us how many bytes the plugin is + // ready to handle - we have to keep calling WriteReady and + // Write until the buffer is empty + while (amountRead > 0) + { + if (callbacks->writeready != NULL) + { +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + numtowrite = CallNPP_WriteReadyProc(callbacks->writeready, + npp, + &mNPStream); +#endif + + if (numtowrite > amountRead) + numtowrite = amountRead; + } + else // if WriteReady is not supported by the plugin, just write the whole buffer + numtowrite = length; + + // if WriteReady returned 0, the plugin is not ready to handle the data, + // so just skip the Write until WriteReady returns a >0 value + if(numtowrite > 0) + { +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + writeCount = CallNPP_WriteProc(callbacks->write, + npp, + &mNPStream, + mPosition, + numtowrite, + (void *)buffer); + if(writeCount < 0) + return NS_ERROR_FAILURE; +#endif + amountRead -= numtowrite; + mPosition += numtowrite; + } + } + + return NS_OK; +} + +NS_IMETHODIMP +ns4xPluginStreamListener::OnFileAvailable(nsIPluginStreamInfo* pluginInfo, const char* fileName) +{ + const NPPluginFuncs *callbacks; + NPP npp; + + pluginInfo->GetURL(&mNPStream.url); + + mInst->GetCallbacks(&callbacks); + mInst->GetNPP(&npp); + + if (callbacks->asfile == NULL) + return NS_OK; + +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + CallNPP_StreamAsFileProc(callbacks->asfile, + npp, + &mNPStream, + fileName); +#endif + + return NS_OK; +} + +NS_IMETHODIMP +ns4xPluginStreamListener::OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status) +{ + const NPPluginFuncs *callbacks; + NPP npp; + NPError error; + + pluginInfo->GetURL(&mNPStream.url); + pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified)); + + mInst->GetCallbacks(&callbacks); + mInst->GetNPP(&npp); + + if (callbacks->destroystream != NULL) + { + // XXX need to convert status to NPReason +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + error = CallNPP_DestroyStreamProc(callbacks->destroystream, + npp, + &mNPStream, + NPRES_DONE); + if(error != NPERR_NO_ERROR) + return NS_ERROR_FAILURE; +#endif + } + + // check to see if we have a call back + if (callbacks->urlnotify != NULL && mNotifyData != nsnull) + { +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + CallNPP_URLNotifyProc(callbacks->urlnotify, + npp, + mNPStream.url, + nsPluginReason_Done, + mNotifyData); +#endif + } + + return NS_OK; +} + +NS_IMETHODIMP +ns4xPluginStreamListener::GetStreamType(nsPluginStreamType *result) +{ + *result = mStreamType; + return NS_OK; +} + +ns4xPluginInstance :: ns4xPluginInstance(NPPluginFuncs* callbacks) + : fCallbacks(callbacks) +{ + NS_INIT_REFCNT(); + + NS_ASSERTION(fCallbacks != NULL, "null callbacks"); + + // Initialize the NPP structure. + + fNPP.pdata = NULL; + fNPP.ndata = this; + + fPeer = nsnull; + + mWindowless = PR_FALSE; + mTransparent = PR_FALSE; + mStarted = PR_FALSE; +} + + +ns4xPluginInstance :: ~ns4xPluginInstance(void) +{ + NS_RELEASE(fPeer); +} + + +//////////////////////////////////////////////////////////////////////// + +NS_IMPL_ADDREF(ns4xPluginInstance); +NS_IMPL_RELEASE(ns4xPluginInstance); + +static NS_DEFINE_IID(kIPluginInstanceIID, NS_IPLUGININSTANCE_IID); +static NS_DEFINE_IID(kIPluginTagInfoIID, NS_IPLUGINTAGINFO_IID); +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + +NS_IMETHODIMP ns4xPluginInstance :: QueryInterface(const nsIID& iid, void** instance) +{ + if (instance == NULL) + return NS_ERROR_NULL_POINTER; + + if (iid.Equals(kIPluginInstanceIID)) + { + *instance = (void *)(nsIPluginInstance *)this; + AddRef(); + return NS_OK; + } + + if (iid.Equals(kISupportsIID)) + { + *instance = (void *)(nsISupports *)this; + AddRef(); + return NS_OK; + } + + return NS_NOINTERFACE; +} + + +//////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP ns4xPluginInstance :: Initialize(nsIPluginInstancePeer* peer) +{ + return InitializePlugin(peer); +} + +NS_IMETHODIMP ns4xPluginInstance :: GetPeer(nsIPluginInstancePeer* *resultingPeer) +{ + NS_ADDREF(fPeer); + *resultingPeer = fPeer; + + return NS_OK; +} + +NS_IMETHODIMP ns4xPluginInstance::Start(void) +{ + printf("instance start called\n"); + if(mStarted) + return NS_OK; + else + return InitializePlugin(fPeer); +} + +NS_IMETHODIMP ns4xPluginInstance::Stop(void) +{ + NPError error; + + printf("instance stop/destroy called\n"); + if (fCallbacks->destroy == NULL) + return NS_ERROR_FAILURE; // XXX right error? + + NPSavedData *sdata; + +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + error = (nsresult)CallNPP_DestroyProc(fCallbacks->destroy, + &fNPP, &sdata); // saved data +#endif + + 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); + +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + error = CallNPP_NewProc(fCallbacks->newp, + (char *)mimetype, + &fNPP, + (PRUint16)mode, + count, + (char**)names, + (char**)values, + NULL); // saved data +#endif + + if(error != NPERR_NO_ERROR) + rv = NS_ERROR_FAILURE; + + mStarted = PR_TRUE; + + return rv; +} + +NS_IMETHODIMP ns4xPluginInstance::Destroy(void) +{ + printf("instance destroy called\n"); + // destruction is handled in the Stop call + return NS_OK; +} + +NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window) +{ + // XXX 4.x plugins don't want a SetWindow(NULL). + + if (window == NULL || mStarted == PR_FALSE) + return NS_OK; + + NPError error; + + if (fCallbacks->setwindow) + { + // XXX Turns out that NPPluginWindow and NPWindow are structurally + // identical (on purpose!), so there's no need to make a copy. + +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + error = CallNPP_SetWindowProc(fCallbacks->setwindow, + &fNPP, + (NPWindow*) window); +#endif + + // XXX In the old code, we'd just ignore any errors coming + // back from the plugin's SetWindow(). Is this the correct + // behavior?!? + + if (error != NPERR_NO_ERROR) + printf("error in setwindow %d\n", error); + } + + return NS_OK; +} + +/* NOTE: the caller must free the stream listener */ + +NS_IMETHODIMP ns4xPluginInstance::NewStream(nsIPluginStreamListener** listener) +{ + nsISupports* stream = nsnull; + stream = (nsISupports *)(nsIPluginStreamListener *)new ns4xPluginStreamListener(this, nsnull); + + if(stream == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + nsresult res = stream->QueryInterface(kIPluginStreamListenerIID, (void**)listener); + + // If we didn't get the right interface, clean up + if (res != NS_OK) + delete stream; + + return res; +} + +nsresult ns4xPluginInstance::NewNotifyStream(nsIPluginStreamListener** listener, void* notifyData) +{ + *listener = new ns4xPluginStreamListener(this, notifyData); + return NS_OK; +} + +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"); + PRInt16 res = 0; + + if (fCallbacks->event) + { +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. +#ifdef XP_MAC + res = CallNPP_HandleEventProc(fCallbacks->event, + &fNPP, + (void*) event->event); +#endif + +#ifdef XP_WIN //~~~ + NPEvent npEvent; + npEvent.event = event->event; + npEvent.wParam = event->wParam; + npEvent.lParam = event->lParam; + res = CallNPP_HandleEventProc(fCallbacks->event, + &fNPP, + (void*)&npEvent); +#endif + +#endif + + *handled = res; + } + + + return NS_OK; +} + +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; +} + +nsresult ns4xPluginInstance::GetNPP(NPP* aNPP) +{ + if(aNPP != nsnull) + *aNPP = &fNPP; + else + return NS_ERROR_NULL_POINTER; + + return NS_OK; +} + +nsresult ns4xPluginInstance::GetCallbacks(const NPPluginFuncs ** aCallbacks) +{ + if(aCallbacks != nsnull) + *aCallbacks = fCallbacks; + else + return NS_ERROR_NULL_POINTER; + + return NS_OK; +} + +nsresult ns4xPluginInstance :: SetWindowless(PRBool aWindowless) +{ + mWindowless = aWindowless; + return NS_OK; +} + +nsresult ns4xPluginInstance :: SetTransparent(PRBool aTransparent) +{ + mTransparent = aTransparent; + return NS_OK; +} diff --git a/modules/plugin/base/src/nsPluginsDir.h b/modules/plugin/base/src/nsPluginsDir.h index e8ae6c556747..5cc865d59128 100644 --- a/modules/plugin/base/src/nsPluginsDir.h +++ b/modules/plugin/base/src/nsPluginsDir.h @@ -1,90 +1,90 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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 nsPluginsDir_h___ -#define nsPluginsDir_h___ - -#include "nsError.h" -#include "nsFileSpec.h" - -/** - * Provides a cross-platform way to obtain the location of the plugins - * directory. Once constructed, can be used with nsDirectoryIterator to - * scan the plugins directory. An nsPluginFileSpec can be constructed from the - * nsFileSpec returned by the iterator. - */ -class nsPluginsDir : public nsFileSpec { -public: - /** - * Locates the plugins directory in a platform-dependent manner. - */ - nsPluginsDir(); - virtual ~nsPluginsDir(); - - /** - * Determines whether or not the given file is actually a plugin file. - */ - PRBool IsPluginFile(const nsFileSpec& fileSpec); -}; - -struct PRLibrary; - -struct nsPluginInfo { - PRUint32 fPluginInfoSize; // indicates how large the structure is currently. - char* fName; // name of the plugin - char* fDescription; // etc. - char* fMimeType; - char* fMimeDescription; - char* fExtensions; - PRUint32 fVariantCount; - char** fMimeTypeArray; - char** fMimeDescriptionArray; - char** fExtensionArray; - char* fFileName; -}; - -/** - * Provides cross-platform access to a plugin file. Deals with reading - * properties from the plugin file, and loading the plugin's shared - * library. Insulates core nsIPluginHost implementations from these - * details. - */ -class nsPluginFile : public nsFileSpec { - PRLibrary* pLibrary; -public: - /** - * If spec corresponds to a valid plugin file, constructs a reference - * to a plugin file on disk. Plugins are typically located using the - * nsPluginsDir class. - */ - nsPluginFile(const nsFileSpec& spec); - virtual ~nsPluginFile(); - - /** - * Loads the plugin into memory using NSPR's shared-library loading - * mechanism. Handles platform differences in loading shared libraries. - */ - nsresult LoadPlugin(PRLibrary* &outLibrary); - - /** - * Obtains all of the information currently available for this plugin. - */ - nsresult GetPluginInfo(nsPluginInfo &outPluginInfo); -}; - -#endif /* nsPluginsDir_h___ */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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 nsPluginsDir_h___ +#define nsPluginsDir_h___ + +#include "nsError.h" +#include "nsFileSpec.h" + +/** + * Provides a cross-platform way to obtain the location of the plugins + * directory. Once constructed, can be used with nsDirectoryIterator to + * scan the plugins directory. An nsPluginFileSpec can be constructed from the + * nsFileSpec returned by the iterator. + */ +class nsPluginsDir : public nsFileSpec { +public: + /** + * Locates the plugins directory in a platform-dependent manner. + */ + nsPluginsDir(); + virtual ~nsPluginsDir(); + + /** + * Determines whether or not the given file is actually a plugin file. + */ + PRBool IsPluginFile(const nsFileSpec& fileSpec); +}; + +struct PRLibrary; + +struct nsPluginInfo { + PRUint32 fPluginInfoSize; // indicates how large the structure is currently. + char* fName; // name of the plugin + char* fDescription; // etc. + char* fMimeType; + char* fMimeDescription; + char* fExtensions; + PRUint32 fVariantCount; + char** fMimeTypeArray; + char** fMimeDescriptionArray; + char** fExtensionArray; + char* fFileName; +}; + +/** + * Provides cross-platform access to a plugin file. Deals with reading + * properties from the plugin file, and loading the plugin's shared + * library. Insulates core nsIPluginHost implementations from these + * details. + */ +class nsPluginFile : public nsFileSpec { + PRLibrary* pLibrary; +public: + /** + * If spec corresponds to a valid plugin file, constructs a reference + * to a plugin file on disk. Plugins are typically located using the + * nsPluginsDir class. + */ + nsPluginFile(const nsFileSpec& spec); + virtual ~nsPluginFile(); + + /** + * Loads the plugin into memory using NSPR's shared-library loading + * mechanism. Handles platform differences in loading shared libraries. + */ + nsresult LoadPlugin(PRLibrary* &outLibrary); + + /** + * Obtains all of the information currently available for this plugin. + */ + nsresult GetPluginInfo(nsPluginInfo &outPluginInfo); +}; + +#endif /* nsPluginsDir_h___ */ diff --git a/modules/plugin/base/src/nsPluginsDirUNIX.cpp b/modules/plugin/base/src/nsPluginsDirUNIX.cpp index f563caecf6d6..9bcb4980922e 100644 --- a/modules/plugin/base/src/nsPluginsDirUNIX.cpp +++ b/modules/plugin/base/src/nsPluginsDirUNIX.cpp @@ -1,247 +1,247 @@ -/* -*- 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. - */ - -/* - nsPluginsDirUNIX.cpp - - UNIX implementation of the nsPluginsDir/nsPluginsFile classes. - - by Alex Musil - */ - -#include "nsPluginsDir.h" -#include "prlink.h" -#include "plstr.h" -#include "prmem.h" - -#include "nsSpecialSystemDirectory.h" - -/* Local helper functions */ - -static char* GetFileName(const char* pathname) -{ - const char* filename = nsnull; - - // this is most likely a path, so skip to the filename - filename = PL_strrchr(pathname, '/'); - if(filename) - ++filename; - else - filename = pathname; - - return PL_strdup(filename); -} - -static PRUint32 CalculateVariantCount(char* mimeTypes) -{ - PRUint32 variants = 0; - char* index = mimeTypes; - while (*index) - { - if (*index == ';') - variants++; - - ++index; - } - return variants; -} - -static char** MakeStringArray(PRUint32 variants, char* data) -{ - char** buffer = NULL; - char* index = data; - PRUint32 count = 0; - - buffer = (char **)PR_Malloc(variants * sizeof(char *)); - buffer[count++] = index; - - while (*index && count/plugins and ~/.mozilla/plugins. There - // doesn't seem to be any way to do this in the current nsPluginsDir code, which is disheartening. - // - - // use MOZILLA_FIVE_HOME/plugins - - nsSpecialSystemDirectory sysdir(nsSpecialSystemDirectory::OS_CurrentProcessDirectory); - sysdir += "plugins"; - const char *pluginsDir = sysdir.GetCString(); // native path - if (pluginsDir != NULL) - { - const char* allocPath; - - allocPath = PL_strdup(pluginsDir); - *(nsFileSpec*)this = allocPath; - } -} - -nsPluginsDir::~nsPluginsDir() -{ - // do nothing -} - -PRBool nsPluginsDir::IsPluginFile(const nsFileSpec& fileSpec) -{ - const char* pathname = fileSpec.GetCString(); - -#ifdef NS_DEBUG - printf("IsPluginFile(%s)\n", pathname); -#endif - - return PR_TRUE; -} - -/////////////////////////////////////////////////////////////////////////// - -/* nsPluginFile implementation */ - -nsPluginFile::nsPluginFile(const nsFileSpec& spec) - : nsFileSpec(spec) -{ - // nada -} - -nsPluginFile::~nsPluginFile() -{ - // nada -} - -/** - * Loads the plugin into memory using NSPR's shared-library loading - * mechanism. Handles platform differences in loading shared libraries. - */ -nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary) -{ - const char* path = this->GetCString(); - pLibrary = outLibrary = PR_LoadLibrary(path); - -#ifdef NS_DEBUG - printf("LoadPlugin() %s returned %lx\n",path,pLibrary); -#endif - - return NS_OK; -} - -typedef char* (*UNIX_Plugin_GetMIMEDescription)(); - - -/** - * Obtains all of the information currently available for this plugin. - */ -nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info) -{ - const char *path = this->GetCString(); - char *mimedescr,*mdesc,*start,*nexttoc,*mtype,*exten,*descr; - int i,num; - - UNIX_Plugin_GetMIMEDescription procedure = nsnull; - mimedescr=""; - - if(procedure = (UNIX_Plugin_GetMIMEDescription)PR_FindSymbol(pLibrary,"NP_GetMIMEDescription")) { - mimedescr = procedure(); - } else { -#ifdef NS_DEBUG - printf("Cannot get plugin info: no GetMIMEDescription procedure!\n"); -#endif - return NS_ERROR_FAILURE; - } - - info.fName = GetFileName(path); - -#ifdef NS_DEBUG - printf("GetMIMEDescription() %lx returned \"%s\"\n",procedure,mimedescr); -#endif - - // copy string - - mdesc = (char *)PR_Malloc(strlen(mimedescr)+1); - strcpy(mdesc,mimedescr); - num=CalculateVariantCount(mimedescr)+1; - info.fVariantCount = num; - - info.fMimeTypeArray =(char **)PR_Malloc(num * sizeof(char *)); - info.fMimeDescriptionArray =(char **)PR_Malloc(num * sizeof(char *)); - info.fExtensionArray =(char **)PR_Malloc(num * sizeof(char *)); - - start=mdesc; - for(i=0;i/plugins and ~/.mozilla/plugins. There + // doesn't seem to be any way to do this in the current nsPluginsDir code, which is disheartening. + // + + // use MOZILLA_FIVE_HOME/plugins + + nsSpecialSystemDirectory sysdir(nsSpecialSystemDirectory::OS_CurrentProcessDirectory); + sysdir += "plugins"; + const char *pluginsDir = sysdir.GetCString(); // native path + if (pluginsDir != NULL) + { + const char* allocPath; + + allocPath = PL_strdup(pluginsDir); + *(nsFileSpec*)this = allocPath; + } +} + +nsPluginsDir::~nsPluginsDir() +{ + // do nothing +} + +PRBool nsPluginsDir::IsPluginFile(const nsFileSpec& fileSpec) +{ + const char* pathname = fileSpec.GetCString(); + +#ifdef NS_DEBUG + printf("IsPluginFile(%s)\n", pathname); +#endif + + return PR_TRUE; +} + +/////////////////////////////////////////////////////////////////////////// + +/* nsPluginFile implementation */ + +nsPluginFile::nsPluginFile(const nsFileSpec& spec) + : nsFileSpec(spec) +{ + // nada +} + +nsPluginFile::~nsPluginFile() +{ + // nada +} + +/** + * Loads the plugin into memory using NSPR's shared-library loading + * mechanism. Handles platform differences in loading shared libraries. + */ +nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary) +{ + const char* path = this->GetCString(); + pLibrary = outLibrary = PR_LoadLibrary(path); + +#ifdef NS_DEBUG + printf("LoadPlugin() %s returned %lx\n",path,pLibrary); +#endif + + return NS_OK; +} + +typedef char* (*UNIX_Plugin_GetMIMEDescription)(); + + +/** + * Obtains all of the information currently available for this plugin. + */ +nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info) +{ + const char *path = this->GetCString(); + char *mimedescr,*mdesc,*start,*nexttoc,*mtype,*exten,*descr; + int i,num; + + UNIX_Plugin_GetMIMEDescription procedure = nsnull; + mimedescr=""; + + if(procedure = (UNIX_Plugin_GetMIMEDescription)PR_FindSymbol(pLibrary,"NP_GetMIMEDescription")) { + mimedescr = procedure(); + } else { +#ifdef NS_DEBUG + printf("Cannot get plugin info: no GetMIMEDescription procedure!\n"); +#endif + return NS_ERROR_FAILURE; + } + + info.fName = GetFileName(path); + +#ifdef NS_DEBUG + printf("GetMIMEDescription() %lx returned \"%s\"\n",procedure,mimedescr); +#endif + + // copy string + + mdesc = (char *)PR_Malloc(strlen(mimedescr)+1); + strcpy(mdesc,mimedescr); + num=CalculateVariantCount(mimedescr)+1; + info.fVariantCount = num; + + info.fMimeTypeArray =(char **)PR_Malloc(num * sizeof(char *)); + info.fMimeDescriptionArray =(char **)PR_Malloc(num * sizeof(char *)); + info.fExtensionArray =(char **)PR_Malloc(num * sizeof(char *)); + + start=mdesc; + for(i=0;i -#endif - -//////////////////////////////////////////////////////////////////////// - -NPNetscapeFuncs ns4xPlugin::CALLBACKS; -nsIPluginManager * ns4xPlugin::mPluginManager; -nsIAllocator * ns4xPlugin::mMalloc; - -void -ns4xPlugin::CheckClassInitialized(void) -{ - static PRBool initialized = FALSE; - - if (initialized) - return; - - mPluginManager = nsnull; - mMalloc = nsnull; - - // XXX It'd be nice to make this const and initialize it - // statically... - CALLBACKS.size = sizeof(CALLBACKS); - CALLBACKS.version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; - -#if !TARGET_CARBON -// pinkerton - these macros rely on BuildRoutineDescriptor(), which is no longer in -// Carbon. Our easy solution to this is to drop support for 68K plugins. Now we just -// need to do the work... - CALLBACKS.geturl = NewNPN_GetURLProc(_geturl); - CALLBACKS.posturl = NewNPN_PostURLProc(_posturl); - CALLBACKS.requestread = NewNPN_RequestReadProc(_requestread); - CALLBACKS.newstream = NewNPN_NewStreamProc(_newstream); - CALLBACKS.write = NewNPN_WriteProc(_write); - CALLBACKS.destroystream = NewNPN_DestroyStreamProc(_destroystream); - CALLBACKS.status = NewNPN_StatusProc(_status); - CALLBACKS.uagent = NewNPN_UserAgentProc(_useragent); - CALLBACKS.memalloc = NewNPN_MemAllocProc(_memalloc); - CALLBACKS.memfree = NewNPN_MemFreeProc(_memfree); - CALLBACKS.memflush = NewNPN_MemFlushProc(_memflush); - CALLBACKS.reloadplugins = NewNPN_ReloadPluginsProc(_reloadplugins); - CALLBACKS.getJavaEnv = NewNPN_GetJavaEnvProc(_getJavaEnv); - CALLBACKS.getJavaPeer = NewNPN_GetJavaPeerProc(_getJavaPeer); - CALLBACKS.geturlnotify = NewNPN_GetURLNotifyProc(_geturlnotify); - CALLBACKS.posturlnotify = NewNPN_PostURLNotifyProc(_posturlnotify); - CALLBACKS.getvalue = NewNPN_GetValueProc(_getvalue); - CALLBACKS.setvalue = NewNPN_SetValueProc(_setvalue); - CALLBACKS.invalidaterect = NewNPN_InvalidateRectProc(_invalidaterect); - CALLBACKS.invalidateregion = NewNPN_InvalidateRegionProc(_invalidateregion); - CALLBACKS.forceredraw = NewNPN_ForceRedrawProc(_forceredraw); -#endif - - initialized = TRUE; -}; - -//////////////////////////////////////////////////////////////////////// -// nsISupports stuff - -NS_IMPL_ADDREF(ns4xPlugin); -NS_IMPL_RELEASE(ns4xPlugin); - -//static NS_DEFINE_IID(kILiveConnectPluginIID, NS_ILIVECONNECTPLUGIN_IID); -static NS_DEFINE_IID(kIPluginIID, NS_IPLUGIN_IID); -static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); -static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); -static NS_DEFINE_IID(kIWindowlessPluginInstancePeerIID, NS_IWINDOWLESSPLUGININSTANCEPEER_IID); -static NS_DEFINE_IID(kPluginManagerCID, NS_PLUGINMANAGER_CID); -static NS_DEFINE_IID(kIPluginManagerIID, NS_IPLUGINMANAGER_IID); -static NS_DEFINE_IID(kAllocatorCID, NS_ALLOCATOR_CID); -static NS_DEFINE_IID(kIAllocatorIID, NS_IALLOCATOR_IID); -static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID); - -//////////////////////////////////////////////////////////////////////// - -ns4xPlugin::ns4xPlugin(NPPluginFuncs* callbacks, NP_PLUGINSHUTDOWN aShutdown, nsIServiceManager* serviceMgr) -{ - NS_INIT_REFCNT(); - - memcpy((void*) &fCallbacks, (void*) callbacks, sizeof(fCallbacks)); - fShutdownEntry = aShutdown; - - // set up the connections to the plugin manager - if (nsnull == mPluginManager) - serviceMgr->GetService(kPluginManagerCID, kIPluginManagerIID, (nsISupports**)&mPluginManager); - - if (nsnull == mMalloc) - serviceMgr->GetService(kAllocatorCID, kIAllocatorIID, (nsISupports**)&mMalloc); -} - - -ns4xPlugin::~ns4xPlugin(void) -{ - -} - - -nsresult -ns4xPlugin::QueryInterface(const nsIID& iid, void** instance) -{ - if (instance == NULL) - return NS_ERROR_NULL_POINTER; - - if (iid.Equals(kIPluginIID)) - { - *instance = (void *)(nsIPlugin *)this; - AddRef(); - return NS_OK; - } - - if (iid.Equals(kIFactoryIID)) - { - *instance = (void *)(nsIFactory *)this; - AddRef(); - return NS_OK; - } - - if (iid.Equals(kISupportsIID)) - { - *instance = (void *)(nsISupports *)this; - AddRef(); - return NS_OK; - } - - return NS_NOINTERFACE; -} - -#ifdef XP_MAC -static char* p2cstrdup(StringPtr pstr) -{ - int len = pstr[0]; - char* cstr = new char[len + 1]; - if (cstr != NULL) { - ::BlockMoveData(pstr + 1, cstr, len); - cstr[len] = '\0'; - } - return cstr; -} - -void -ns4xPlugin::SetPluginRefNum(short aRefNum) -{ - fPluginRefNum = aRefNum; -} -#endif - -//////////////////////////////////////////////////////////////////////// -// Static factory method. -// - -/* - CreatePlugin() - -------------- - Handles the initialization of old, 4x style plugins. Creates the ns4xPlugin object. - One ns4xPlugin object exists per Plugin (not instance). -*/ - -nsresult -ns4xPlugin::CreatePlugin(nsPluginTag* pluginTag, nsIServiceManager* serviceMgr) -{ - CheckClassInitialized(); - printf("debug: edburns ns4xPlugin::CreatePlugin\n"); -#ifdef XP_UNIX - - ns4xPlugin *plptr; - - NPPluginFuncs callbacks; - memset((void*) &callbacks, 0, sizeof(callbacks)); - callbacks.size = sizeof(callbacks); - - printf("debug: edburns ns4xPlugin::CreatePlugin: cleared callbacks\n"); - - NP_PLUGINSHUTDOWN pfnShutdown = - (NP_PLUGINSHUTDOWN)PR_FindSymbol(pluginTag->mLibrary, "NP_Shutdown"); - - // create the new plugin handler - pluginTag->mEntryPoint = plptr = new ns4xPlugin(&callbacks, pfnShutdown, serviceMgr); - - if (pluginTag->mEntryPoint == NULL) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(pluginTag->mEntryPoint); - - // we must init here because the plugin may call NPN functions - // when we call into the NP_Initialize entry point - NPN functions - // require that mBrowserManager be set up - plptr->Initialize(); - - NP_PLUGINUNIXINIT pfnInitialize = - (NP_PLUGINUNIXINIT)PR_FindSymbol(pluginTag->mLibrary, "NP_Initialize"); - - if (pfnInitialize == NULL) - return NS_ERROR_UNEXPECTED; // XXX Right error? - - if (pfnInitialize(&(ns4xPlugin::CALLBACKS),&callbacks) != NS_OK) - return NS_ERROR_UNEXPECTED; - printf("debug: edburns: ns4xPlugin::CreatePlugin: callbacks->newstream: %p\n", - callbacks.newstream); - - // now copy function table back to ns4xPlugin instance - memcpy((void*) &(plptr->fCallbacks), (void*)&callbacks, sizeof(callbacks)); -#endif - -#ifdef XP_PC - // XXX this only applies on Windows - NP_GETENTRYPOINTS pfnGetEntryPoints = - (NP_GETENTRYPOINTS)PR_FindSymbol(pluginTag->mLibrary, "NP_GetEntryPoints"); - - if (pfnGetEntryPoints == NULL) - return NS_ERROR_FAILURE; - - NPPluginFuncs callbacks; - memset((void*) &callbacks, 0, sizeof(callbacks)); - - callbacks.size = sizeof(callbacks); - - if (pfnGetEntryPoints(&callbacks) != NS_OK) - return NS_ERROR_FAILURE; // XXX - -#ifdef XP_PC // XXX This is really XP, but we need to figure out how to do HIBYTE() - if (HIBYTE(callbacks.version) < NP_VERSION_MAJOR) - return NS_ERROR_FAILURE; -#endif - - NP_PLUGINSHUTDOWN pfnShutdown = - (NP_PLUGINSHUTDOWN)PR_FindSymbol(pluginTag->mLibrary, "NP_Shutdown"); - - // create the new plugin handler - pluginTag->mEntryPoint = new ns4xPlugin(&callbacks, pfnShutdown, serviceMgr); - - if (pluginTag->mEntryPoint == NULL) - return NS_ERROR_OUT_OF_MEMORY; - - NS_ADDREF(pluginTag->mEntryPoint); - - // we must init here because the plugin may call NPN functions - // when we call into the NP_Initialize entry point - NPN functions - // require that mBrowserManager be set up - pluginTag->mEntryPoint->Initialize(); - - // 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, - // I don't want to break the plugins already in the field, so - // we'll accept either name - - NP_PLUGININIT pfnInitialize = - (NP_PLUGININIT)PR_FindSymbol(pluginTag->mLibrary, "NP_Initialize"); - - if (!pfnInitialize) { - pfnInitialize = - (NP_PLUGININIT)PR_FindSymbol(pluginTag->mLibrary, "NP_PluginInit"); - } - - if (pfnInitialize == NULL) - return NS_ERROR_UNEXPECTED; // XXX Right error? - - if (pfnInitialize(&(ns4xPlugin::CALLBACKS)) != NS_OK) - return NS_ERROR_UNEXPECTED; -#endif - -#ifdef XP_MAC - // get the mainRD entry point - NP_MAIN pfnMain = (NP_MAIN) PR_FindSymbol(pluginTag->mLibrary, "mainRD"); - if(pfnMain == NULL) - return NS_ERROR_FAILURE; - - NPP_ShutdownUPP pfnShutdown; - NPPluginFuncs callbacks; - memset((void*) &callbacks, 0, sizeof(callbacks)); - callbacks.size = sizeof(callbacks); - - nsPluginsDir pluginsDir; - if(!pluginsDir.Valid()) - return NS_ERROR_FAILURE; - - short appRefNum = ::CurResFile(); - short pluginRefNum; - for(nsDirectoryIterator iter(pluginsDir); iter.Exists(); iter++) - { - const nsFileSpec& file = iter; - if (pluginsDir.IsPluginFile(file)) - { - FSSpec spec = file; - char* fileName = p2cstrdup(spec.name); - if(!PL_strcmp(fileName, pluginTag->mFileName)) - { - Boolean targetIsFolder, wasAliased; - OSErr err = ::ResolveAliasFile(&spec, true, &targetIsFolder, &wasAliased); - pluginRefNum = ::FSpOpenResFile(&spec, fsRdPerm); - } - } - } - - // call into the entry point - if(CallNPP_MainEntryProc(pfnMain, &(ns4xPlugin::CALLBACKS), &callbacks, &pfnShutdown) != NPERR_NO_ERROR) - return NS_ERROR_FAILURE; - - ::UseResFile(appRefNum); - - if ((callbacks.version >> 8) < NP_VERSION_MAJOR) - return NS_ERROR_FAILURE; - - // create the new plugin handler - ns4xPlugin* plugin = new ns4xPlugin(&callbacks, (NP_PLUGINSHUTDOWN)pfnShutdown, serviceMgr); - - if(plugin == NULL) - return NS_ERROR_OUT_OF_MEMORY; - - plugin->SetPluginRefNum(pluginRefNum); - - pluginTag->mEntryPoint = plugin; - - NS_ADDREF(pluginTag->mEntryPoint); -#endif - -#ifdef XP_UNIX - return NS_ERROR_FAILURE; -#endif - - return NS_OK; -} - -/* - CreateInstance() - ---------------- - Creates a ns4xPluginInstance object. -*/ - -nsresult ns4xPlugin :: CreateInstance(nsISupports *aOuter, - const nsIID &aIID, - void **aResult) -{ - if (aResult == NULL) { - return NS_ERROR_NULL_POINTER; - } - - *aResult = NULL; - - nsISupports *inst; - - inst = nsnull; - inst = (nsISupports *)(nsIPluginInstance *)new ns4xPluginInstance(&fCallbacks); - - if (inst == NULL) { - return NS_ERROR_OUT_OF_MEMORY; - } - - nsresult res = inst->QueryInterface(aIID, aResult); - - if (res != NS_OK) { - // We didn't get the right interface, so clean up - delete inst; - } - - return res; -} - -nsresult ns4xPlugin :: LockFactory(PRBool aLock) -{ - // Not implemented in simplest case. - return NS_OK; -} - -NS_METHOD ns4xPlugin :: CreatePluginInstance(nsISupports *aOuter, REFNSIID aIID, - const char* aPluginMIMEType, - void **aResult) -{ - return CreateInstance(aOuter, aIID, aResult); -} - -nsresult -ns4xPlugin::Initialize(void) -{ - return NS_OK; -} - -nsresult -ns4xPlugin::Shutdown(void) -{ - if (nsnull != fShutdownEntry) - { -#ifdef NS_DEBUG - printf("shutting down plugin %08x\n",(int)this); -#endif -#ifdef XP_MAC - CallNPP_ShutdownProc(fShutdownEntry); - ::CloseResFile(fPluginRefNum); -#else - fShutdownEntry(); -#endif - - fShutdownEntry = nsnull; - } - - NS_IF_RELEASE(mPluginManager); - NS_IF_RELEASE(mMalloc); - - return NS_OK; -} - -nsresult -ns4xPlugin::GetMIMEDescription(const char* *resultingDesc) -{ - printf("plugin getmimedescription called\n"); - *resultingDesc = ""; - return NS_OK; // XXX make a callback, etc. -} - -nsresult -ns4xPlugin::GetValue(nsPluginVariable variable, void *value) -{ -printf("plugin getvalue %d called\n", variable); - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////// -// -// Static callbacks that get routed back through the new C++ API -// - -NPError NP_EXPORT -ns4xPlugin::_geturl(NPP npp, const char* relativeURL, const char* target) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - NS_ASSERTION(mPluginManager != NULL, "null manager"); - - if (inst == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginStreamListener* listener = nsnull; - if(target == nsnull) - inst->NewStream(&listener); - - if(mPluginManager->GetURL(inst, relativeURL, target, listener) != NS_OK) - return NPERR_GENERIC_ERROR; - - return NPERR_NO_ERROR; -} - -NPError NP_EXPORT -ns4xPlugin::_geturlnotify(NPP npp, const char* relativeURL, const char* target, - void* notifyData) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - NS_ASSERTION(mPluginManager != NULL, "null manager"); - - if (inst == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginStreamListener* listener = nsnull; - if(target == nsnull) - ((ns4xPluginInstance*)inst)->NewNotifyStream(&listener, notifyData); - - if(mPluginManager->GetURL(inst, relativeURL, target, listener) != NS_OK) - return NPERR_GENERIC_ERROR; - - return NPERR_NO_ERROR; -} - - -NPError NP_EXPORT -ns4xPlugin::_posturlnotify(NPP npp, const char* relativeURL, const char *target, - uint32 len, const char *buf, NPBool file, - void* notifyData) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - NS_ASSERTION(mPluginManager != NULL, "null manager"); - - if (inst == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginStreamListener* listener = nsnull; - if(target == nsnull) - ((ns4xPluginInstance*)inst)->NewNotifyStream(&listener, notifyData); - - if(mPluginManager->PostURL(inst, relativeURL, len, buf, file, target, listener) != NS_OK) - return NPERR_GENERIC_ERROR; - - return NPERR_NO_ERROR; -} - - -NPError NP_EXPORT -ns4xPlugin::_posturl(NPP npp, const char* relativeURL, const char *target, uint32 len, - const char *buf, NPBool file) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - NS_ASSERTION(mPluginManager != NULL, "null manager"); - - if (inst == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginStreamListener* listener = nsnull; - if(target == nsnull) - inst->NewStream(&listener); - - if(mPluginManager->PostURL(inst, relativeURL, len, buf, file, target, listener) != NS_OK) - return NPERR_GENERIC_ERROR; - - return NPERR_NO_ERROR; -} - -//////////////////////////////////////////////////////////////////////// - -/** - * A little helper class used to wrap up plugin manager streams (that is, - * streams from the plugin to the browser). - */ -class ns4xStreamWrapper -{ -protected: - nsIOutputStream *fStream; - NPStream fNPStream; - -public: - ns4xStreamWrapper(nsIOutputStream* stream); - ~ns4xStreamWrapper(); - - void GetStream(nsIOutputStream* &result); - - NPStream* - GetNPStream(void) { - return &fNPStream; - }; -}; - -ns4xStreamWrapper::ns4xStreamWrapper(nsIOutputStream* stream) - : fStream(stream) -{ - NS_ASSERTION(stream != NULL, "bad stream"); - - fStream = stream; - NS_ADDREF(fStream); - - memset(&fNPStream, 0, sizeof(fNPStream)); - fNPStream.ndata = (void*) this; -} - -ns4xStreamWrapper::~ns4xStreamWrapper(void) -{ - fStream->Close(); - NS_IF_RELEASE(fStream); -} - - -void -ns4xStreamWrapper::GetStream(nsIOutputStream* &result) -{ - result = fStream; - NS_IF_ADDREF(fStream); -} - -//////////////////////////////////////////////////////////////////////// - - -NPError NP_EXPORT -ns4xPlugin::_newstream(NPP npp, NPMIMEType type, const char* window, NPStream* *result) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - - if (inst == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - nsIOutputStream* stream; - nsIPluginInstancePeer *peer; - - if (NS_OK == inst->GetPeer(&peer)) - { - if (peer->NewStream((const char*) type, window, &stream) != NS_OK) - { - NS_RELEASE(peer); - return NPERR_GENERIC_ERROR; - } - - ns4xStreamWrapper* wrapper = new ns4xStreamWrapper(stream); - - if (wrapper == NULL) - { - NS_RELEASE(peer); - NS_RELEASE(stream); - return NPERR_OUT_OF_MEMORY_ERROR; - } - - (*result) = wrapper->GetNPStream(); - - NS_RELEASE(peer); - - return NPERR_NO_ERROR; - } - else - return NPERR_GENERIC_ERROR; -} - -int32 NP_EXPORT -ns4xPlugin::_write(NPP npp, NPStream *pstream, int32 len, void *buffer) -{ - // negative return indicates failure to the plugin - if(!npp) - return -1; - - ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata; - NS_ASSERTION(wrapper != NULL, "null stream"); - - if (wrapper == NULL) - return -1; - - nsIOutputStream* stream; - wrapper->GetStream(stream); - - PRUint32 count = 0; - nsresult rv = stream->Write((char *)buffer, len, &count); - NS_RELEASE(stream); - - if(rv != NS_OK) - return -1; - - return (int32)count; -} - -NPError NP_EXPORT -ns4xPlugin::_destroystream(NPP npp, NPStream *pstream, NPError reason) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - nsISupports* stream = (nsISupports*) pstream->ndata; - nsIPluginStreamListener* listener; - - // DestroyStream can kill two kinds of streams: NPP derived and - // NPN derived. - // check to see if they're trying to kill a NPP stream - if(stream->QueryInterface(kIPluginStreamListenerIID, (void**)&listener) == NS_OK) - { - // XXX we should try to kill this listener here somehow - NS_RELEASE(listener); - return NPERR_NO_ERROR; - } - - ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata; - - NS_ASSERTION(wrapper != NULL, "null wrapper"); - - if (wrapper == NULL) - return NPERR_INVALID_PARAM; - - // This will release the wrapped nsIOutputStream. - delete wrapper; - - return NPERR_NO_ERROR; -} - -void NP_EXPORT -ns4xPlugin::_status(NPP npp, const char *message) -{ - if(!npp) - return; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - - if (inst == NULL) - return; - - nsIPluginInstancePeer *peer; - - if (NS_OK == inst->GetPeer(&peer)) - { - peer->ShowStatus(message); - NS_RELEASE(peer); - } -} - -void NP_EXPORT -ns4xPlugin::_memfree (void *ptr) -{ - if(ptr) - mMalloc->Free(ptr); -} - -uint32 NP_EXPORT -ns4xPlugin::_memflush(uint32 size) -{ - mMalloc->HeapMinimize(); - - return 0; -} - -void NP_EXPORT -ns4xPlugin::_reloadplugins(NPBool reloadPages) -{ - mPluginManager->ReloadPlugins(reloadPages); -} - -void NP_EXPORT -ns4xPlugin::_invalidaterect(NPP npp, NPRect *invalidRect) -{ - if(!npp) - return; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - - if (inst == NULL) - return; - - nsIPluginInstancePeer *peer; - nsIWindowlessPluginInstancePeer *wpeer; - - if (NS_OK == inst->GetPeer(&peer)) - { - if (NS_OK == peer->QueryInterface(kIWindowlessPluginInstancePeerIID, (void **)&wpeer)) - { - // XXX nsRect & NPRect are structurally equivalent - wpeer->InvalidateRect((nsPluginRect *)invalidRect); - NS_RELEASE(wpeer); - } - - NS_RELEASE(peer); - } -} - -void NP_EXPORT -ns4xPlugin::_invalidateregion(NPP npp, NPRegion invalidRegion) -{ - if(!npp) - return; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - - if (inst == NULL) - return; - - nsIPluginInstancePeer *peer; - nsIWindowlessPluginInstancePeer *wpeer; - - if (NS_OK == inst->GetPeer(&peer)) - { - if (NS_OK == peer->QueryInterface(kIWindowlessPluginInstancePeerIID, (void **)&wpeer)) - { - // XXX nsRegion & NPRegion are typedef'd to the same thing - wpeer->InvalidateRegion((nsPluginRegion)invalidRegion); - NS_RELEASE(wpeer); - } - - NS_RELEASE(peer); - } -} - -void NP_EXPORT -ns4xPlugin::_forceredraw(NPP npp) -{ - if(!npp) - return; - - nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - - if (inst == NULL) - return; - - nsIPluginInstancePeer *peer; - nsIWindowlessPluginInstancePeer *wpeer; - - if (NS_OK == inst->GetPeer(&peer)) - { - if (NS_OK == peer->QueryInterface(kIWindowlessPluginInstancePeerIID, (void **)&wpeer)) - { - wpeer->ForceRedraw(); - NS_RELEASE(wpeer); - } - - NS_RELEASE(peer); - } -} - -NPError NP_EXPORT -ns4xPlugin::_getvalue(NPP npp, NPNVariable variable, void *result) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - switch(variable) - { -#ifdef XP_UNIX - case NPNVxDisplay : return NPERR_GENERIC_ERROR; - - case NPNVxtAppContext : return NPERR_GENERIC_ERROR; -#endif - -#ifdef XP_PC - case NPNVnetscapeWindow : return NPERR_GENERIC_ERROR; -#endif - - case NPNVjavascriptEnabledBool : *(NPBool*)result = TRUE; return NPERR_NO_ERROR; - - case NPNVasdEnabledBool : *(NPBool*)result = FALSE; return NPERR_NO_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 -ns4xPlugin::_setvalue(NPP npp, NPPVariable variable, void *result) -{ - if(!npp) - return NPERR_INVALID_INSTANCE_ERROR; - - ns4xPluginInstance *inst = (ns4xPluginInstance *) npp->ndata; - - NS_ASSERTION(inst != NULL, "null instance"); - - if (inst == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - switch (variable) - { - case NPPVpluginWindowBool: - { - NPBool bWindowless = !(*((NPBool *)result)); - return inst->SetWindowless(bWindowless); - } - - case NPPVpluginTransparentBool: - return inst->SetTransparent(*((NPBool *)result)); - - default: - return NPERR_NO_ERROR; - } - -#if 0 - nsIPluginInstancePeer *peer; - - if (NS_OK == inst->GetPeer(&peer)) - { - nsresult rv; - - // XXX Note that for backwards compatibility, the old NPPVariables - // map correctly to NPPluginVariables. - rv = peer->SetValue((nsPluginInstancePeerVariable)variable, result); - NS_RELEASE(peer); - return rv; - } - else - return NS_ERROR_UNEXPECTED; -#endif -} - -NPError NP_EXPORT -ns4xPlugin::_requestread(NPStream *pstream, NPByteRange *rangeList) -{ - return NPERR_STREAM_NOT_SEEKABLE; -} - - -//////////////////////////////////////////////////////////////////////// -// -// On 68K Mac (XXX still supported?), we need to make sure that the -// pointers are in D0 for the following functions that return pointers. -// - -#if defined(XP_MAC) && !defined(powerc) -#pragma pointers_in_D0 -#endif - - -JRIEnv* NP_EXPORT -ns4xPlugin::_getJavaEnv(void) -{ - return NULL; -} - -const char * NP_EXPORT -ns4xPlugin::_useragent(NPP npp) -{ - NS_ASSERTION(mPluginManager != NULL, "null pluginmanager"); - - if (mPluginManager == NULL) - return NULL; - - char *retstr; - - mPluginManager->UserAgent((const char **)&retstr); - - return retstr; -} - -void * NP_EXPORT -ns4xPlugin::_memalloc (uint32 size) -{ - return mMalloc->Alloc(size); -} - -java_lang_Class* NP_EXPORT -ns4xPlugin::_getJavaClass(void* handle) -{ - return NULL; -} - - - -jref NP_EXPORT -ns4xPlugin::_getJavaPeer(NPP npp) -{ - return NULL; -} - - -// eof +/* -*- 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. + */ + +// TODO: Implement Java callbacks + +#include "xp_core.h" +#include "nsplugin.h" +#include "ns4xPlugin.h" +#include "ns4xPluginInstance.h" +#include "nsIServiceManager.h" +#include "nsIAllocator.h" +#include "nsIPluginStreamListener.h" +#include "nsPluginsDir.h" + +#ifdef XP_MAC +#include +#endif + +//////////////////////////////////////////////////////////////////////// + +NPNetscapeFuncs ns4xPlugin::CALLBACKS; +nsIPluginManager * ns4xPlugin::mPluginManager; +nsIAllocator * ns4xPlugin::mMalloc; + +void +ns4xPlugin::CheckClassInitialized(void) +{ + static PRBool initialized = FALSE; + + if (initialized) + return; + + mPluginManager = nsnull; + mMalloc = nsnull; + + // XXX It'd be nice to make this const and initialize it + // statically... + CALLBACKS.size = sizeof(CALLBACKS); + CALLBACKS.version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; + +#if !TARGET_CARBON +// pinkerton - these macros rely on BuildRoutineDescriptor(), which is no longer in +// Carbon. Our easy solution to this is to drop support for 68K plugins. Now we just +// need to do the work... + CALLBACKS.geturl = NewNPN_GetURLProc(_geturl); + CALLBACKS.posturl = NewNPN_PostURLProc(_posturl); + CALLBACKS.requestread = NewNPN_RequestReadProc(_requestread); + CALLBACKS.newstream = NewNPN_NewStreamProc(_newstream); + CALLBACKS.write = NewNPN_WriteProc(_write); + CALLBACKS.destroystream = NewNPN_DestroyStreamProc(_destroystream); + CALLBACKS.status = NewNPN_StatusProc(_status); + CALLBACKS.uagent = NewNPN_UserAgentProc(_useragent); + CALLBACKS.memalloc = NewNPN_MemAllocProc(_memalloc); + CALLBACKS.memfree = NewNPN_MemFreeProc(_memfree); + CALLBACKS.memflush = NewNPN_MemFlushProc(_memflush); + CALLBACKS.reloadplugins = NewNPN_ReloadPluginsProc(_reloadplugins); + CALLBACKS.getJavaEnv = NewNPN_GetJavaEnvProc(_getJavaEnv); + CALLBACKS.getJavaPeer = NewNPN_GetJavaPeerProc(_getJavaPeer); + CALLBACKS.geturlnotify = NewNPN_GetURLNotifyProc(_geturlnotify); + CALLBACKS.posturlnotify = NewNPN_PostURLNotifyProc(_posturlnotify); + CALLBACKS.getvalue = NewNPN_GetValueProc(_getvalue); + CALLBACKS.setvalue = NewNPN_SetValueProc(_setvalue); + CALLBACKS.invalidaterect = NewNPN_InvalidateRectProc(_invalidaterect); + CALLBACKS.invalidateregion = NewNPN_InvalidateRegionProc(_invalidateregion); + CALLBACKS.forceredraw = NewNPN_ForceRedrawProc(_forceredraw); +#endif + + initialized = TRUE; +}; + +//////////////////////////////////////////////////////////////////////// +// nsISupports stuff + +NS_IMPL_ADDREF(ns4xPlugin); +NS_IMPL_RELEASE(ns4xPlugin); + +//static NS_DEFINE_IID(kILiveConnectPluginIID, NS_ILIVECONNECTPLUGIN_IID); +static NS_DEFINE_IID(kIPluginIID, NS_IPLUGIN_IID); +static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID); +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +static NS_DEFINE_IID(kIWindowlessPluginInstancePeerIID, NS_IWINDOWLESSPLUGININSTANCEPEER_IID); +static NS_DEFINE_IID(kPluginManagerCID, NS_PLUGINMANAGER_CID); +static NS_DEFINE_IID(kIPluginManagerIID, NS_IPLUGINMANAGER_IID); +static NS_DEFINE_IID(kAllocatorCID, NS_ALLOCATOR_CID); +static NS_DEFINE_IID(kIAllocatorIID, NS_IALLOCATOR_IID); +static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID); + +//////////////////////////////////////////////////////////////////////// + +ns4xPlugin::ns4xPlugin(NPPluginFuncs* callbacks, NP_PLUGINSHUTDOWN aShutdown, nsIServiceManager* serviceMgr) +{ + NS_INIT_REFCNT(); + + memcpy((void*) &fCallbacks, (void*) callbacks, sizeof(fCallbacks)); + fShutdownEntry = aShutdown; + + // set up the connections to the plugin manager + if (nsnull == mPluginManager) + serviceMgr->GetService(kPluginManagerCID, kIPluginManagerIID, (nsISupports**)&mPluginManager); + + if (nsnull == mMalloc) + serviceMgr->GetService(kAllocatorCID, kIAllocatorIID, (nsISupports**)&mMalloc); +} + + +ns4xPlugin::~ns4xPlugin(void) +{ + +} + + +nsresult +ns4xPlugin::QueryInterface(const nsIID& iid, void** instance) +{ + if (instance == NULL) + return NS_ERROR_NULL_POINTER; + + if (iid.Equals(kIPluginIID)) + { + *instance = (void *)(nsIPlugin *)this; + AddRef(); + return NS_OK; + } + + if (iid.Equals(kIFactoryIID)) + { + *instance = (void *)(nsIFactory *)this; + AddRef(); + return NS_OK; + } + + if (iid.Equals(kISupportsIID)) + { + *instance = (void *)(nsISupports *)this; + AddRef(); + return NS_OK; + } + + return NS_NOINTERFACE; +} + +#ifdef XP_MAC +static char* p2cstrdup(StringPtr pstr) +{ + int len = pstr[0]; + char* cstr = new char[len + 1]; + if (cstr != NULL) { + ::BlockMoveData(pstr + 1, cstr, len); + cstr[len] = '\0'; + } + return cstr; +} + +void +ns4xPlugin::SetPluginRefNum(short aRefNum) +{ + fPluginRefNum = aRefNum; +} +#endif + +//////////////////////////////////////////////////////////////////////// +// Static factory method. +// + +/* + CreatePlugin() + -------------- + Handles the initialization of old, 4x style plugins. Creates the ns4xPlugin object. + One ns4xPlugin object exists per Plugin (not instance). +*/ + +nsresult +ns4xPlugin::CreatePlugin(nsPluginTag* pluginTag, nsIServiceManager* serviceMgr) +{ + CheckClassInitialized(); + printf("debug: edburns ns4xPlugin::CreatePlugin\n"); +#ifdef XP_UNIX + + ns4xPlugin *plptr; + + NPPluginFuncs callbacks; + memset((void*) &callbacks, 0, sizeof(callbacks)); + callbacks.size = sizeof(callbacks); + + printf("debug: edburns ns4xPlugin::CreatePlugin: cleared callbacks\n"); + + NP_PLUGINSHUTDOWN pfnShutdown = + (NP_PLUGINSHUTDOWN)PR_FindSymbol(pluginTag->mLibrary, "NP_Shutdown"); + + // create the new plugin handler + pluginTag->mEntryPoint = plptr = new ns4xPlugin(&callbacks, pfnShutdown, serviceMgr); + + if (pluginTag->mEntryPoint == NULL) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(pluginTag->mEntryPoint); + + // we must init here because the plugin may call NPN functions + // when we call into the NP_Initialize entry point - NPN functions + // require that mBrowserManager be set up + plptr->Initialize(); + + NP_PLUGINUNIXINIT pfnInitialize = + (NP_PLUGINUNIXINIT)PR_FindSymbol(pluginTag->mLibrary, "NP_Initialize"); + + if (pfnInitialize == NULL) + return NS_ERROR_UNEXPECTED; // XXX Right error? + + if (pfnInitialize(&(ns4xPlugin::CALLBACKS),&callbacks) != NS_OK) + return NS_ERROR_UNEXPECTED; + printf("debug: edburns: ns4xPlugin::CreatePlugin: callbacks->newstream: %p\n", + callbacks.newstream); + + // now copy function table back to ns4xPlugin instance + memcpy((void*) &(plptr->fCallbacks), (void*)&callbacks, sizeof(callbacks)); +#endif + +#ifdef XP_PC + // XXX this only applies on Windows + NP_GETENTRYPOINTS pfnGetEntryPoints = + (NP_GETENTRYPOINTS)PR_FindSymbol(pluginTag->mLibrary, "NP_GetEntryPoints"); + + if (pfnGetEntryPoints == NULL) + return NS_ERROR_FAILURE; + + NPPluginFuncs callbacks; + memset((void*) &callbacks, 0, sizeof(callbacks)); + + callbacks.size = sizeof(callbacks); + + if (pfnGetEntryPoints(&callbacks) != NS_OK) + return NS_ERROR_FAILURE; // XXX + +#ifdef XP_PC // XXX This is really XP, but we need to figure out how to do HIBYTE() + if (HIBYTE(callbacks.version) < NP_VERSION_MAJOR) + return NS_ERROR_FAILURE; +#endif + + NP_PLUGINSHUTDOWN pfnShutdown = + (NP_PLUGINSHUTDOWN)PR_FindSymbol(pluginTag->mLibrary, "NP_Shutdown"); + + // create the new plugin handler + pluginTag->mEntryPoint = new ns4xPlugin(&callbacks, pfnShutdown, serviceMgr); + + if (pluginTag->mEntryPoint == NULL) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(pluginTag->mEntryPoint); + + // we must init here because the plugin may call NPN functions + // when we call into the NP_Initialize entry point - NPN functions + // require that mBrowserManager be set up + pluginTag->mEntryPoint->Initialize(); + + // 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, + // I don't want to break the plugins already in the field, so + // we'll accept either name + + NP_PLUGININIT pfnInitialize = + (NP_PLUGININIT)PR_FindSymbol(pluginTag->mLibrary, "NP_Initialize"); + + if (!pfnInitialize) { + pfnInitialize = + (NP_PLUGININIT)PR_FindSymbol(pluginTag->mLibrary, "NP_PluginInit"); + } + + if (pfnInitialize == NULL) + return NS_ERROR_UNEXPECTED; // XXX Right error? + + if (pfnInitialize(&(ns4xPlugin::CALLBACKS)) != NS_OK) + return NS_ERROR_UNEXPECTED; +#endif + +#ifdef XP_MAC + // get the mainRD entry point + NP_MAIN pfnMain = (NP_MAIN) PR_FindSymbol(pluginTag->mLibrary, "mainRD"); + if(pfnMain == NULL) + return NS_ERROR_FAILURE; + + NPP_ShutdownUPP pfnShutdown; + NPPluginFuncs callbacks; + memset((void*) &callbacks, 0, sizeof(callbacks)); + callbacks.size = sizeof(callbacks); + + nsPluginsDir pluginsDir; + if(!pluginsDir.Valid()) + return NS_ERROR_FAILURE; + + short appRefNum = ::CurResFile(); + short pluginRefNum; + for(nsDirectoryIterator iter(pluginsDir); iter.Exists(); iter++) + { + const nsFileSpec& file = iter; + if (pluginsDir.IsPluginFile(file)) + { + FSSpec spec = file; + char* fileName = p2cstrdup(spec.name); + if(!PL_strcmp(fileName, pluginTag->mFileName)) + { + Boolean targetIsFolder, wasAliased; + OSErr err = ::ResolveAliasFile(&spec, true, &targetIsFolder, &wasAliased); + pluginRefNum = ::FSpOpenResFile(&spec, fsRdPerm); + } + } + } + + // call into the entry point + if(CallNPP_MainEntryProc(pfnMain, &(ns4xPlugin::CALLBACKS), &callbacks, &pfnShutdown) != NPERR_NO_ERROR) + return NS_ERROR_FAILURE; + + ::UseResFile(appRefNum); + + if ((callbacks.version >> 8) < NP_VERSION_MAJOR) + return NS_ERROR_FAILURE; + + // create the new plugin handler + ns4xPlugin* plugin = new ns4xPlugin(&callbacks, (NP_PLUGINSHUTDOWN)pfnShutdown, serviceMgr); + + if(plugin == NULL) + return NS_ERROR_OUT_OF_MEMORY; + + plugin->SetPluginRefNum(pluginRefNum); + + pluginTag->mEntryPoint = plugin; + + NS_ADDREF(pluginTag->mEntryPoint); +#endif + +#ifdef XP_UNIX + return NS_ERROR_FAILURE; +#endif + + return NS_OK; +} + +/* + CreateInstance() + ---------------- + Creates a ns4xPluginInstance object. +*/ + +nsresult ns4xPlugin :: CreateInstance(nsISupports *aOuter, + const nsIID &aIID, + void **aResult) +{ + if (aResult == NULL) { + return NS_ERROR_NULL_POINTER; + } + + *aResult = NULL; + + nsISupports *inst; + + inst = nsnull; + inst = (nsISupports *)(nsIPluginInstance *)new ns4xPluginInstance(&fCallbacks); + + if (inst == NULL) { + return NS_ERROR_OUT_OF_MEMORY; + } + + nsresult res = inst->QueryInterface(aIID, aResult); + + if (res != NS_OK) { + // We didn't get the right interface, so clean up + delete inst; + } + + return res; +} + +nsresult ns4xPlugin :: LockFactory(PRBool aLock) +{ + // Not implemented in simplest case. + return NS_OK; +} + +NS_METHOD ns4xPlugin :: CreatePluginInstance(nsISupports *aOuter, REFNSIID aIID, + const char* aPluginMIMEType, + void **aResult) +{ + return CreateInstance(aOuter, aIID, aResult); +} + +nsresult +ns4xPlugin::Initialize(void) +{ + return NS_OK; +} + +nsresult +ns4xPlugin::Shutdown(void) +{ + if (nsnull != fShutdownEntry) + { +#ifdef NS_DEBUG + printf("shutting down plugin %08x\n",(int)this); +#endif +#ifdef XP_MAC + CallNPP_ShutdownProc(fShutdownEntry); + ::CloseResFile(fPluginRefNum); +#else + fShutdownEntry(); +#endif + + fShutdownEntry = nsnull; + } + + NS_IF_RELEASE(mPluginManager); + NS_IF_RELEASE(mMalloc); + + return NS_OK; +} + +nsresult +ns4xPlugin::GetMIMEDescription(const char* *resultingDesc) +{ + printf("plugin getmimedescription called\n"); + *resultingDesc = ""; + return NS_OK; // XXX make a callback, etc. +} + +nsresult +ns4xPlugin::GetValue(nsPluginVariable variable, void *value) +{ +printf("plugin getvalue %d called\n", variable); + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////// +// +// Static callbacks that get routed back through the new C++ API +// + +NPError NP_EXPORT +ns4xPlugin::_geturl(NPP npp, const char* relativeURL, const char* target) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + NS_ASSERTION(mPluginManager != NULL, "null manager"); + + if (inst == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginStreamListener* listener = nsnull; + if(target == nsnull) + inst->NewStream(&listener); + + if(mPluginManager->GetURL(inst, relativeURL, target, listener) != NS_OK) + return NPERR_GENERIC_ERROR; + + return NPERR_NO_ERROR; +} + +NPError NP_EXPORT +ns4xPlugin::_geturlnotify(NPP npp, const char* relativeURL, const char* target, + void* notifyData) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + NS_ASSERTION(mPluginManager != NULL, "null manager"); + + if (inst == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginStreamListener* listener = nsnull; + if(target == nsnull) + ((ns4xPluginInstance*)inst)->NewNotifyStream(&listener, notifyData); + + if(mPluginManager->GetURL(inst, relativeURL, target, listener) != NS_OK) + return NPERR_GENERIC_ERROR; + + return NPERR_NO_ERROR; +} + + +NPError NP_EXPORT +ns4xPlugin::_posturlnotify(NPP npp, const char* relativeURL, const char *target, + uint32 len, const char *buf, NPBool file, + void* notifyData) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + NS_ASSERTION(mPluginManager != NULL, "null manager"); + + if (inst == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginStreamListener* listener = nsnull; + if(target == nsnull) + ((ns4xPluginInstance*)inst)->NewNotifyStream(&listener, notifyData); + + if(mPluginManager->PostURL(inst, relativeURL, len, buf, file, target, listener) != NS_OK) + return NPERR_GENERIC_ERROR; + + return NPERR_NO_ERROR; +} + + +NPError NP_EXPORT +ns4xPlugin::_posturl(NPP npp, const char* relativeURL, const char *target, uint32 len, + const char *buf, NPBool file) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + NS_ASSERTION(mPluginManager != NULL, "null manager"); + + if (inst == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginStreamListener* listener = nsnull; + if(target == nsnull) + inst->NewStream(&listener); + + if(mPluginManager->PostURL(inst, relativeURL, len, buf, file, target, listener) != NS_OK) + return NPERR_GENERIC_ERROR; + + return NPERR_NO_ERROR; +} + +//////////////////////////////////////////////////////////////////////// + +/** + * A little helper class used to wrap up plugin manager streams (that is, + * streams from the plugin to the browser). + */ +class ns4xStreamWrapper +{ +protected: + nsIOutputStream *fStream; + NPStream fNPStream; + +public: + ns4xStreamWrapper(nsIOutputStream* stream); + ~ns4xStreamWrapper(); + + void GetStream(nsIOutputStream* &result); + + NPStream* + GetNPStream(void) { + return &fNPStream; + }; +}; + +ns4xStreamWrapper::ns4xStreamWrapper(nsIOutputStream* stream) + : fStream(stream) +{ + NS_ASSERTION(stream != NULL, "bad stream"); + + fStream = stream; + NS_ADDREF(fStream); + + memset(&fNPStream, 0, sizeof(fNPStream)); + fNPStream.ndata = (void*) this; +} + +ns4xStreamWrapper::~ns4xStreamWrapper(void) +{ + fStream->Close(); + NS_IF_RELEASE(fStream); +} + + +void +ns4xStreamWrapper::GetStream(nsIOutputStream* &result) +{ + result = fStream; + NS_IF_ADDREF(fStream); +} + +//////////////////////////////////////////////////////////////////////// + + +NPError NP_EXPORT +ns4xPlugin::_newstream(NPP npp, NPMIMEType type, const char* window, NPStream* *result) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + + if (inst == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + nsIOutputStream* stream; + nsIPluginInstancePeer *peer; + + if (NS_OK == inst->GetPeer(&peer)) + { + if (peer->NewStream((const char*) type, window, &stream) != NS_OK) + { + NS_RELEASE(peer); + return NPERR_GENERIC_ERROR; + } + + ns4xStreamWrapper* wrapper = new ns4xStreamWrapper(stream); + + if (wrapper == NULL) + { + NS_RELEASE(peer); + NS_RELEASE(stream); + return NPERR_OUT_OF_MEMORY_ERROR; + } + + (*result) = wrapper->GetNPStream(); + + NS_RELEASE(peer); + + return NPERR_NO_ERROR; + } + else + return NPERR_GENERIC_ERROR; +} + +int32 NP_EXPORT +ns4xPlugin::_write(NPP npp, NPStream *pstream, int32 len, void *buffer) +{ + // negative return indicates failure to the plugin + if(!npp) + return -1; + + ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata; + NS_ASSERTION(wrapper != NULL, "null stream"); + + if (wrapper == NULL) + return -1; + + nsIOutputStream* stream; + wrapper->GetStream(stream); + + PRUint32 count = 0; + nsresult rv = stream->Write((char *)buffer, len, &count); + NS_RELEASE(stream); + + if(rv != NS_OK) + return -1; + + return (int32)count; +} + +NPError NP_EXPORT +ns4xPlugin::_destroystream(NPP npp, NPStream *pstream, NPError reason) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + nsISupports* stream = (nsISupports*) pstream->ndata; + nsIPluginStreamListener* listener; + + // DestroyStream can kill two kinds of streams: NPP derived and + // NPN derived. + // check to see if they're trying to kill a NPP stream + if(stream->QueryInterface(kIPluginStreamListenerIID, (void**)&listener) == NS_OK) + { + // XXX we should try to kill this listener here somehow + NS_RELEASE(listener); + return NPERR_NO_ERROR; + } + + ns4xStreamWrapper* wrapper = (ns4xStreamWrapper*) pstream->ndata; + + NS_ASSERTION(wrapper != NULL, "null wrapper"); + + if (wrapper == NULL) + return NPERR_INVALID_PARAM; + + // This will release the wrapped nsIOutputStream. + delete wrapper; + + return NPERR_NO_ERROR; +} + +void NP_EXPORT +ns4xPlugin::_status(NPP npp, const char *message) +{ + if(!npp) + return; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + + if (inst == NULL) + return; + + nsIPluginInstancePeer *peer; + + if (NS_OK == inst->GetPeer(&peer)) + { + peer->ShowStatus(message); + NS_RELEASE(peer); + } +} + +void NP_EXPORT +ns4xPlugin::_memfree (void *ptr) +{ + if(ptr) + mMalloc->Free(ptr); +} + +uint32 NP_EXPORT +ns4xPlugin::_memflush(uint32 size) +{ + mMalloc->HeapMinimize(); + + return 0; +} + +void NP_EXPORT +ns4xPlugin::_reloadplugins(NPBool reloadPages) +{ + mPluginManager->ReloadPlugins(reloadPages); +} + +void NP_EXPORT +ns4xPlugin::_invalidaterect(NPP npp, NPRect *invalidRect) +{ + if(!npp) + return; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + + if (inst == NULL) + return; + + nsIPluginInstancePeer *peer; + nsIWindowlessPluginInstancePeer *wpeer; + + if (NS_OK == inst->GetPeer(&peer)) + { + if (NS_OK == peer->QueryInterface(kIWindowlessPluginInstancePeerIID, (void **)&wpeer)) + { + // XXX nsRect & NPRect are structurally equivalent + wpeer->InvalidateRect((nsPluginRect *)invalidRect); + NS_RELEASE(wpeer); + } + + NS_RELEASE(peer); + } +} + +void NP_EXPORT +ns4xPlugin::_invalidateregion(NPP npp, NPRegion invalidRegion) +{ + if(!npp) + return; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + + if (inst == NULL) + return; + + nsIPluginInstancePeer *peer; + nsIWindowlessPluginInstancePeer *wpeer; + + if (NS_OK == inst->GetPeer(&peer)) + { + if (NS_OK == peer->QueryInterface(kIWindowlessPluginInstancePeerIID, (void **)&wpeer)) + { + // XXX nsRegion & NPRegion are typedef'd to the same thing + wpeer->InvalidateRegion((nsPluginRegion)invalidRegion); + NS_RELEASE(wpeer); + } + + NS_RELEASE(peer); + } +} + +void NP_EXPORT +ns4xPlugin::_forceredraw(NPP npp) +{ + if(!npp) + return; + + nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + + if (inst == NULL) + return; + + nsIPluginInstancePeer *peer; + nsIWindowlessPluginInstancePeer *wpeer; + + if (NS_OK == inst->GetPeer(&peer)) + { + if (NS_OK == peer->QueryInterface(kIWindowlessPluginInstancePeerIID, (void **)&wpeer)) + { + wpeer->ForceRedraw(); + NS_RELEASE(wpeer); + } + + NS_RELEASE(peer); + } +} + +NPError NP_EXPORT +ns4xPlugin::_getvalue(NPP npp, NPNVariable variable, void *result) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + switch(variable) + { +#ifdef XP_UNIX + case NPNVxDisplay : return NPERR_GENERIC_ERROR; + + case NPNVxtAppContext : return NPERR_GENERIC_ERROR; +#endif + +#ifdef XP_PC + case NPNVnetscapeWindow : return NPERR_GENERIC_ERROR; +#endif + + case NPNVjavascriptEnabledBool : *(NPBool*)result = TRUE; return NPERR_NO_ERROR; + + case NPNVasdEnabledBool : *(NPBool*)result = FALSE; return NPERR_NO_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 +ns4xPlugin::_setvalue(NPP npp, NPPVariable variable, void *result) +{ + if(!npp) + return NPERR_INVALID_INSTANCE_ERROR; + + ns4xPluginInstance *inst = (ns4xPluginInstance *) npp->ndata; + + NS_ASSERTION(inst != NULL, "null instance"); + + if (inst == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + switch (variable) + { + case NPPVpluginWindowBool: + { + NPBool bWindowless = !(*((NPBool *)result)); + return inst->SetWindowless(bWindowless); + } + + case NPPVpluginTransparentBool: + return inst->SetTransparent(*((NPBool *)result)); + + default: + return NPERR_NO_ERROR; + } + +#if 0 + nsIPluginInstancePeer *peer; + + if (NS_OK == inst->GetPeer(&peer)) + { + nsresult rv; + + // XXX Note that for backwards compatibility, the old NPPVariables + // map correctly to NPPluginVariables. + rv = peer->SetValue((nsPluginInstancePeerVariable)variable, result); + NS_RELEASE(peer); + return rv; + } + else + return NS_ERROR_UNEXPECTED; +#endif +} + +NPError NP_EXPORT +ns4xPlugin::_requestread(NPStream *pstream, NPByteRange *rangeList) +{ + return NPERR_STREAM_NOT_SEEKABLE; +} + + +//////////////////////////////////////////////////////////////////////// +// +// On 68K Mac (XXX still supported?), we need to make sure that the +// pointers are in D0 for the following functions that return pointers. +// + +#if defined(XP_MAC) && !defined(powerc) +#pragma pointers_in_D0 +#endif + + +JRIEnv* NP_EXPORT +ns4xPlugin::_getJavaEnv(void) +{ + return NULL; +} + +const char * NP_EXPORT +ns4xPlugin::_useragent(NPP npp) +{ + NS_ASSERTION(mPluginManager != NULL, "null pluginmanager"); + + if (mPluginManager == NULL) + return NULL; + + char *retstr; + + mPluginManager->UserAgent((const char **)&retstr); + + return retstr; +} + +void * NP_EXPORT +ns4xPlugin::_memalloc (uint32 size) +{ + return mMalloc->Alloc(size); +} + +java_lang_Class* NP_EXPORT +ns4xPlugin::_getJavaClass(void* handle) +{ + return NULL; +} + + + +jref NP_EXPORT +ns4xPlugin::_getJavaPeer(NPP npp) +{ + return NULL; +} + + +// eof diff --git a/modules/plugin/nglsrc/ns4xPlugin.h b/modules/plugin/nglsrc/ns4xPlugin.h index fad9bd1d865d..905521275ca4 100644 --- a/modules/plugin/nglsrc/ns4xPlugin.h +++ b/modules/plugin/nglsrc/ns4xPlugin.h @@ -1,249 +1,249 @@ -/* -*- 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 ns4xPlugin_h__ -#define ns4xPlugin_h__ - -#include "nsplugin.h" -#include "prlink.h" // for PRLibrary -#include "npupp.h" -#include "nsPluginHostImpl.h" - -//////////////////////////////////////////////////////////////////////// - -/* - * Use this macro before each exported function - * (between the return address and the function - * itself), to ensure that the function has the - * right calling conventions on Win16. - */ - -#define NP_EXPORT - -//////////////////////////////////////////////////////////////////////// - -// XXX These are defined in platform specific FE directories right now :-/ - -#if defined(XP_PC) || defined(XP_UNIX) || defined(XP_BEOS) -typedef NS_CALLBACK_(NPError, NP_GETENTRYPOINTS) (NPPluginFuncs* pCallbacks); -typedef NS_CALLBACK_(NPError, NP_PLUGININIT) (const NPNetscapeFuncs* pCallbacks); -typedef NS_CALLBACK_(NPError, NP_PLUGINUNIXINIT) (const NPNetscapeFuncs* pCallbacks,NPPluginFuncs* fCallbacks); -typedef NS_CALLBACK_(NPError, NP_PLUGINSHUTDOWN) (void); -#endif - -#ifdef XP_MAC -typedef NS_CALLBACK_(NPError, NP_PLUGINSHUTDOWN) (void); -typedef NS_CALLBACK_(NPError, NP_MAIN) (NPNetscapeFuncs* nCallbacks, NPPluginFuncs* pCallbacks, NPP_ShutdownUPP* unloadUpp); -#endif - -class nsIServiceManager; -class nsIAllocator; - -//////////////////////////////////////////////////////////////////////// - -/** - * A 5.0 wrapper for a 4.x style plugin. - */ - -class ns4xPlugin : public nsIPlugin -{ -public: - - ns4xPlugin(NPPluginFuncs* callbacks, NP_PLUGINSHUTDOWN aShutdown, nsIServiceManager* serviceMgr); - virtual ~ns4xPlugin(void); - - NS_DECL_ISUPPORTS - - //nsIFactory interface - - NS_IMETHOD CreateInstance(nsISupports *aOuter, - REFNSIID aIID, - void **aResult); - - NS_IMETHOD LockFactory(PRBool aLock); - - //nsIPlugin interface - - /** - * Creates a new plugin instance, based on a MIME type. This - * allows different impelementations to be created depending on - * the specified MIME type. - */ - NS_IMETHOD CreatePluginInstance(nsISupports *aOuter, REFNSIID aIID, - const char* aPluginMIMEType, - void **aResult); - - NS_IMETHOD - Initialize(void); - - NS_IMETHOD - Shutdown(void); - - NS_IMETHOD - GetMIMEDescription(const char* *resultingDesc); - - NS_IMETHOD - GetValue(nsPluginVariable variable, void *value); - - //////////////////////////////////////////////////////////////////// - // ns4xPlugin-specific methods - - /** - * A static factory method for constructing 4.x plugins. Constructs - * and initializes an ns4xPlugin object, and returns it in - * result. - */ - - static nsresult - CreatePlugin(nsPluginTag* pluginTag, nsIServiceManager* serviceMgr); - -#ifdef XP_MAC - void - SetPluginRefNum(short aRefNum); -#endif - -protected: - /** - * Ensures that the static CALLBACKS is properly initialized - */ - static void CheckClassInitialized(void); - - //////////////////////////////////////////////////////////////////////// - // Static stub functions that are exported to the 4.x plugin as entry - // points via the CALLBACKS variable. - // - static NPError NP_EXPORT - _requestread(NPStream *pstream, NPByteRange *rangeList); - - static NPError NP_EXPORT - _geturlnotify(NPP npp, const char* relativeURL, const char* target, void* notifyData); - - static NPError NP_EXPORT - _getvalue(NPP npp, NPNVariable variable, void *r_value); - - static NPError NP_EXPORT - _setvalue(NPP npp, NPPVariable variable, void *r_value); - - static NPError NP_EXPORT - _geturl(NPP npp, const char* relativeURL, const char* target); - - static NPError NP_EXPORT - _posturlnotify(NPP npp, const char* relativeURL, const char *target, - uint32 len, const char *buf, NPBool file, void* notifyData); - - static NPError NP_EXPORT - _posturl(NPP npp, const char* relativeURL, const char *target, uint32 len, - const char *buf, NPBool file); - - static NPError NP_EXPORT - _newstream(NPP npp, NPMIMEType type, const char* window, NPStream** pstream); - - static int32 NP_EXPORT - _write(NPP npp, NPStream *pstream, int32 len, void *buffer); - - static NPError NP_EXPORT - _destroystream(NPP npp, NPStream *pstream, NPError reason); - - static void NP_EXPORT - _status(NPP npp, const char *message); - -#if 0 - - static void NP_EXPORT - _registerwindow(NPP npp, void* window); - - static void NP_EXPORT - _unregisterwindow(NPP npp, void* window); - - static int16 NP_EXPORT - _allocateMenuID(NPP npp, NPBool isSubmenu); - -#endif - - static void NP_EXPORT - _memfree (void *ptr); - - static uint32 NP_EXPORT - _memflush(uint32 size); - - static void NP_EXPORT - _reloadplugins(NPBool reloadPages); - - static void NP_EXPORT - _invalidaterect(NPP npp, NPRect *invalidRect); - - static void NP_EXPORT - _invalidateregion(NPP npp, NPRegion invalidRegion); - - static void NP_EXPORT - _forceredraw(NPP npp); - - //////////////////////////////////////////////////////////////////////// - // Anything that returns a pointer needs to be _HERE_ for 68K Mac to - // work. - // - -#if defined(XP_MAC) && !defined(powerc) -#pragma pointers_in_D0 -#endif - - static const char* NP_EXPORT - _useragent(NPP npp); - - static void* NP_EXPORT - _memalloc (uint32 size); - - static JRIEnv* NP_EXPORT - _getJavaEnv(void); - -#if 1 - - static jref NP_EXPORT - _getJavaPeer(NPP npp); - - static java_lang_Class* NP_EXPORT - _getJavaClass(void* handle); - -#endif - -#if defined(XP_MAC) && !defined(powerc) -#pragma pointers_in_A0 -#endif - -#ifdef XP_MAC - short fPluginRefNum; -#endif - - /** - * The plugin-side callbacks that the browser calls. One set of - * plugin callbacks for each plugin. - */ - NPPluginFuncs fCallbacks; - - NP_PLUGINSHUTDOWN fShutdownEntry; - - /** - * The browser-side callbacks that a 4.x-style plugin calls. - */ - static NPNetscapeFuncs CALLBACKS; - - static nsIPluginManager *mPluginManager; - static nsIAllocator *mMalloc; -}; - -#endif // ns4xPlugin_h__ +/* -*- 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 ns4xPlugin_h__ +#define ns4xPlugin_h__ + +#include "nsplugin.h" +#include "prlink.h" // for PRLibrary +#include "npupp.h" +#include "nsPluginHostImpl.h" + +//////////////////////////////////////////////////////////////////////// + +/* + * Use this macro before each exported function + * (between the return address and the function + * itself), to ensure that the function has the + * right calling conventions on Win16. + */ + +#define NP_EXPORT + +//////////////////////////////////////////////////////////////////////// + +// XXX These are defined in platform specific FE directories right now :-/ + +#if defined(XP_PC) || defined(XP_UNIX) || defined(XP_BEOS) +typedef NS_CALLBACK_(NPError, NP_GETENTRYPOINTS) (NPPluginFuncs* pCallbacks); +typedef NS_CALLBACK_(NPError, NP_PLUGININIT) (const NPNetscapeFuncs* pCallbacks); +typedef NS_CALLBACK_(NPError, NP_PLUGINUNIXINIT) (const NPNetscapeFuncs* pCallbacks,NPPluginFuncs* fCallbacks); +typedef NS_CALLBACK_(NPError, NP_PLUGINSHUTDOWN) (void); +#endif + +#ifdef XP_MAC +typedef NS_CALLBACK_(NPError, NP_PLUGINSHUTDOWN) (void); +typedef NS_CALLBACK_(NPError, NP_MAIN) (NPNetscapeFuncs* nCallbacks, NPPluginFuncs* pCallbacks, NPP_ShutdownUPP* unloadUpp); +#endif + +class nsIServiceManager; +class nsIAllocator; + +//////////////////////////////////////////////////////////////////////// + +/** + * A 5.0 wrapper for a 4.x style plugin. + */ + +class ns4xPlugin : public nsIPlugin +{ +public: + + ns4xPlugin(NPPluginFuncs* callbacks, NP_PLUGINSHUTDOWN aShutdown, nsIServiceManager* serviceMgr); + virtual ~ns4xPlugin(void); + + NS_DECL_ISUPPORTS + + //nsIFactory interface + + NS_IMETHOD CreateInstance(nsISupports *aOuter, + REFNSIID aIID, + void **aResult); + + NS_IMETHOD LockFactory(PRBool aLock); + + //nsIPlugin interface + + /** + * Creates a new plugin instance, based on a MIME type. This + * allows different impelementations to be created depending on + * the specified MIME type. + */ + NS_IMETHOD CreatePluginInstance(nsISupports *aOuter, REFNSIID aIID, + const char* aPluginMIMEType, + void **aResult); + + NS_IMETHOD + Initialize(void); + + NS_IMETHOD + Shutdown(void); + + NS_IMETHOD + GetMIMEDescription(const char* *resultingDesc); + + NS_IMETHOD + GetValue(nsPluginVariable variable, void *value); + + //////////////////////////////////////////////////////////////////// + // ns4xPlugin-specific methods + + /** + * A static factory method for constructing 4.x plugins. Constructs + * and initializes an ns4xPlugin object, and returns it in + * result. + */ + + static nsresult + CreatePlugin(nsPluginTag* pluginTag, nsIServiceManager* serviceMgr); + +#ifdef XP_MAC + void + SetPluginRefNum(short aRefNum); +#endif + +protected: + /** + * Ensures that the static CALLBACKS is properly initialized + */ + static void CheckClassInitialized(void); + + //////////////////////////////////////////////////////////////////////// + // Static stub functions that are exported to the 4.x plugin as entry + // points via the CALLBACKS variable. + // + static NPError NP_EXPORT + _requestread(NPStream *pstream, NPByteRange *rangeList); + + static NPError NP_EXPORT + _geturlnotify(NPP npp, const char* relativeURL, const char* target, void* notifyData); + + static NPError NP_EXPORT + _getvalue(NPP npp, NPNVariable variable, void *r_value); + + static NPError NP_EXPORT + _setvalue(NPP npp, NPPVariable variable, void *r_value); + + static NPError NP_EXPORT + _geturl(NPP npp, const char* relativeURL, const char* target); + + static NPError NP_EXPORT + _posturlnotify(NPP npp, const char* relativeURL, const char *target, + uint32 len, const char *buf, NPBool file, void* notifyData); + + static NPError NP_EXPORT + _posturl(NPP npp, const char* relativeURL, const char *target, uint32 len, + const char *buf, NPBool file); + + static NPError NP_EXPORT + _newstream(NPP npp, NPMIMEType type, const char* window, NPStream** pstream); + + static int32 NP_EXPORT + _write(NPP npp, NPStream *pstream, int32 len, void *buffer); + + static NPError NP_EXPORT + _destroystream(NPP npp, NPStream *pstream, NPError reason); + + static void NP_EXPORT + _status(NPP npp, const char *message); + +#if 0 + + static void NP_EXPORT + _registerwindow(NPP npp, void* window); + + static void NP_EXPORT + _unregisterwindow(NPP npp, void* window); + + static int16 NP_EXPORT + _allocateMenuID(NPP npp, NPBool isSubmenu); + +#endif + + static void NP_EXPORT + _memfree (void *ptr); + + static uint32 NP_EXPORT + _memflush(uint32 size); + + static void NP_EXPORT + _reloadplugins(NPBool reloadPages); + + static void NP_EXPORT + _invalidaterect(NPP npp, NPRect *invalidRect); + + static void NP_EXPORT + _invalidateregion(NPP npp, NPRegion invalidRegion); + + static void NP_EXPORT + _forceredraw(NPP npp); + + //////////////////////////////////////////////////////////////////////// + // Anything that returns a pointer needs to be _HERE_ for 68K Mac to + // work. + // + +#if defined(XP_MAC) && !defined(powerc) +#pragma pointers_in_D0 +#endif + + static const char* NP_EXPORT + _useragent(NPP npp); + + static void* NP_EXPORT + _memalloc (uint32 size); + + static JRIEnv* NP_EXPORT + _getJavaEnv(void); + +#if 1 + + static jref NP_EXPORT + _getJavaPeer(NPP npp); + + static java_lang_Class* NP_EXPORT + _getJavaClass(void* handle); + +#endif + +#if defined(XP_MAC) && !defined(powerc) +#pragma pointers_in_A0 +#endif + +#ifdef XP_MAC + short fPluginRefNum; +#endif + + /** + * The plugin-side callbacks that the browser calls. One set of + * plugin callbacks for each plugin. + */ + NPPluginFuncs fCallbacks; + + NP_PLUGINSHUTDOWN fShutdownEntry; + + /** + * The browser-side callbacks that a 4.x-style plugin calls. + */ + static NPNetscapeFuncs CALLBACKS; + + static nsIPluginManager *mPluginManager; + static nsIAllocator *mMalloc; +}; + +#endif // ns4xPlugin_h__ diff --git a/modules/plugin/nglsrc/ns4xPluginInstance.cpp b/modules/plugin/nglsrc/ns4xPluginInstance.cpp index 7343344933f3..1791907846b4 100644 --- a/modules/plugin/nglsrc/ns4xPluginInstance.cpp +++ b/modules/plugin/nglsrc/ns4xPluginInstance.cpp @@ -1,617 +1,617 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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. - */ - -#include "ns4xPluginInstance.h" -#include "nsIPluginStreamListener.h" - -#include "prlog.h" -#include "prmem.h" -#include "nscore.h" - - -class ns4xPluginStreamListener : public nsIPluginStreamListener { - -public: - - NS_DECL_ISUPPORTS - - //////////////////////////////////////////////////////////////////////////// - // from nsIPluginStreamListener: - - NS_IMETHOD - OnStartBinding(nsIPluginStreamInfo* pluginInfo); - - NS_IMETHOD - OnDataAvailable(nsIPluginStreamInfo* pluginInfo, nsIInputStream* input, PRUint32 length); - - NS_IMETHOD - OnFileAvailable( nsIPluginStreamInfo* pluginInfo, const char* fileName); - - NS_IMETHOD - OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status); - - NS_IMETHOD - GetStreamType(nsPluginStreamType *result); - - //////////////////////////////////////////////////////////////////////////// - // ns4xPluginStreamListener specific methods: - - ns4xPluginStreamListener(nsIPluginInstance* inst, void* notifyData); - virtual ~ns4xPluginStreamListener(void); - -protected: - - void* mNotifyData; - ns4xPluginInstance* mInst; - NPStream mNPStream; - PRUint32 mPosition; - nsPluginStreamType mStreamType; -}; - - -//////////////////////////////////////////////////////////////////////////////// -// ns4xPluginStreamListener Methods -//////////////////////////////////////////////////////////////////////////////// - -static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID); - -ns4xPluginStreamListener::ns4xPluginStreamListener(nsIPluginInstance* inst, void* notifyData) - : mNotifyData(notifyData) -{ - NS_INIT_REFCNT(); - mInst = (ns4xPluginInstance*) inst; - mPosition = 0; - - // Initialize the 4.x interface structure - memset(&mNPStream, 0, sizeof(mNPStream)); - - NS_IF_ADDREF(mInst); -} - -ns4xPluginStreamListener::~ns4xPluginStreamListener(void) -{ - NS_IF_RELEASE(mInst); -} - -NS_IMPL_ISUPPORTS(ns4xPluginStreamListener, kIPluginStreamListenerIID); - -NS_IMETHODIMP -ns4xPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo) -{ - - printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding()\n"); - NPP npp; - const NPPluginFuncs *callbacks; - PRBool seekable; - nsMIMEType contentType; - PRUint16 streamType = NP_NORMAL; - NPError error; - - mNPStream.ndata = (void*) this; - pluginInfo->GetURL(&mNPStream.url); - mNPStream.notifyData = mNotifyData; - - pluginInfo->GetLength((PRUint32*)&(mNPStream.end)); - pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified)); - pluginInfo->IsSeekable(&seekable); - pluginInfo->GetContentType(&contentType); - - mInst->GetCallbacks(&callbacks); - mInst->GetNPP(&npp); - - printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding() done GetNPP()\n"); -#if !TARGET_CARBON - printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding() about to call CallNPP_NewStreamProc: callbacks->newstream: %p\n", callbacks->newstream); -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - error = CallNPP_NewStreamProc(callbacks->newstream, - npp, - (char *)contentType, - &mNPStream, - seekable, - &streamType); - if(error != NPERR_NO_ERROR) - return NS_ERROR_FAILURE; -#endif - // translate the old 4x style stream type to the new one - switch(streamType) - { - case NP_NORMAL : mStreamType = nsPluginStreamType_Normal; break; - - case NP_ASFILEONLY : mStreamType = nsPluginStreamType_AsFileOnly; break; - - case NP_ASFILE : mStreamType = nsPluginStreamType_AsFile; break; - - case NP_SEEK : mStreamType = nsPluginStreamType_Seek; break; - - default: return NS_ERROR_FAILURE; - } - - printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding() done switch\n"); - - return NS_OK; -} - -NS_IMETHODIMP -ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo, - nsIInputStream* input, - PRUint32 length) -{ - const NPPluginFuncs *callbacks; - NPP npp; - PRUint32 numtowrite = 0; - PRUint32 amountRead = 0; - PRInt32 writeCount = 0; - - pluginInfo->GetURL(&mNPStream.url); - pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified)); - - mInst->GetCallbacks(&callbacks); - mInst->GetNPP(&npp); - - if (callbacks->write == NULL || length == 0) - return NS_OK; // XXX ? - - // Get the data from the input stream - char* buffer = (char*) PR_Malloc(length); - if (buffer) - input->Read(buffer, length, &amountRead); - - // amountRead tells us how many bytes were put in the buffer - // WriteReady returns to us how many bytes the plugin is - // ready to handle - we have to keep calling WriteReady and - // Write until the buffer is empty - while (amountRead > 0) - { - if (callbacks->writeready != NULL) - { -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - numtowrite = CallNPP_WriteReadyProc(callbacks->writeready, - npp, - &mNPStream); -#endif - - if (numtowrite > amountRead) - numtowrite = amountRead; - } - else // if WriteReady is not supported by the plugin, just write the whole buffer - numtowrite = length; - - // if WriteReady returned 0, the plugin is not ready to handle the data, - // so just skip the Write until WriteReady returns a >0 value - if(numtowrite > 0) - { -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - writeCount = CallNPP_WriteProc(callbacks->write, - npp, - &mNPStream, - mPosition, - numtowrite, - (void *)buffer); - if(writeCount < 0) - return NS_ERROR_FAILURE; -#endif - amountRead -= numtowrite; - mPosition += numtowrite; - } - } - - return NS_OK; -} - -NS_IMETHODIMP -ns4xPluginStreamListener::OnFileAvailable(nsIPluginStreamInfo* pluginInfo, const char* fileName) -{ - const NPPluginFuncs *callbacks; - NPP npp; - - pluginInfo->GetURL(&mNPStream.url); - - mInst->GetCallbacks(&callbacks); - mInst->GetNPP(&npp); - - if (callbacks->asfile == NULL) - return NS_OK; - -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - CallNPP_StreamAsFileProc(callbacks->asfile, - npp, - &mNPStream, - fileName); -#endif - - return NS_OK; -} - -NS_IMETHODIMP -ns4xPluginStreamListener::OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status) -{ - const NPPluginFuncs *callbacks; - NPP npp; - NPError error; - - pluginInfo->GetURL(&mNPStream.url); - pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified)); - - mInst->GetCallbacks(&callbacks); - mInst->GetNPP(&npp); - - if (callbacks->destroystream != NULL) - { - // XXX need to convert status to NPReason -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - error = CallNPP_DestroyStreamProc(callbacks->destroystream, - npp, - &mNPStream, - NPRES_DONE); - if(error != NPERR_NO_ERROR) - return NS_ERROR_FAILURE; -#endif - } - - // check to see if we have a call back - if (callbacks->urlnotify != NULL && mNotifyData != nsnull) - { -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - CallNPP_URLNotifyProc(callbacks->urlnotify, - npp, - mNPStream.url, - nsPluginReason_Done, - mNotifyData); -#endif - } - - return NS_OK; -} - -NS_IMETHODIMP -ns4xPluginStreamListener::GetStreamType(nsPluginStreamType *result) -{ - *result = mStreamType; - return NS_OK; -} - -ns4xPluginInstance :: ns4xPluginInstance(NPPluginFuncs* callbacks) - : fCallbacks(callbacks) -{ - NS_INIT_REFCNT(); - - NS_ASSERTION(fCallbacks != NULL, "null callbacks"); - - // Initialize the NPP structure. - - fNPP.pdata = NULL; - fNPP.ndata = this; - - fPeer = nsnull; - - mWindowless = PR_FALSE; - mTransparent = PR_FALSE; - mStarted = PR_FALSE; -} - - -ns4xPluginInstance :: ~ns4xPluginInstance(void) -{ - NS_RELEASE(fPeer); -} - - -//////////////////////////////////////////////////////////////////////// - -NS_IMPL_ADDREF(ns4xPluginInstance); -NS_IMPL_RELEASE(ns4xPluginInstance); - -static NS_DEFINE_IID(kIPluginInstanceIID, NS_IPLUGININSTANCE_IID); -static NS_DEFINE_IID(kIPluginTagInfoIID, NS_IPLUGINTAGINFO_IID); -static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); - -NS_IMETHODIMP ns4xPluginInstance :: QueryInterface(const nsIID& iid, void** instance) -{ - if (instance == NULL) - return NS_ERROR_NULL_POINTER; - - if (iid.Equals(kIPluginInstanceIID)) - { - *instance = (void *)(nsIPluginInstance *)this; - AddRef(); - return NS_OK; - } - - if (iid.Equals(kISupportsIID)) - { - *instance = (void *)(nsISupports *)this; - AddRef(); - return NS_OK; - } - - return NS_NOINTERFACE; -} - - -//////////////////////////////////////////////////////////////////////// - -NS_IMETHODIMP ns4xPluginInstance :: Initialize(nsIPluginInstancePeer* peer) -{ - return InitializePlugin(peer); -} - -NS_IMETHODIMP ns4xPluginInstance :: GetPeer(nsIPluginInstancePeer* *resultingPeer) -{ - NS_ADDREF(fPeer); - *resultingPeer = fPeer; - - return NS_OK; -} - -NS_IMETHODIMP ns4xPluginInstance::Start(void) -{ - printf("instance start called\n"); - if(mStarted) - return NS_OK; - else - return InitializePlugin(fPeer); -} - -NS_IMETHODIMP ns4xPluginInstance::Stop(void) -{ - NPError error; - - printf("instance stop/destroy called\n"); - if (fCallbacks->destroy == NULL) - return NS_ERROR_FAILURE; // XXX right error? - - NPSavedData *sdata; - -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - error = (nsresult)CallNPP_DestroyProc(fCallbacks->destroy, - &fNPP, &sdata); // saved data -#endif - - 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); - -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - error = CallNPP_NewProc(fCallbacks->newp, - (char *)mimetype, - &fNPP, - (PRUint16)mode, - count, - (char**)names, - (char**)values, - NULL); // saved data -#endif - - if(error != NPERR_NO_ERROR) - rv = NS_ERROR_FAILURE; - - mStarted = PR_TRUE; - - return rv; -} - -NS_IMETHODIMP ns4xPluginInstance::Destroy(void) -{ - printf("instance destroy called\n"); - // destruction is handled in the Stop call - return NS_OK; -} - -NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window) -{ - // XXX 4.x plugins don't want a SetWindow(NULL). - - if (window == NULL || mStarted == PR_FALSE) - return NS_OK; - - NPError error; - - if (fCallbacks->setwindow) - { - // XXX Turns out that NPPluginWindow and NPWindow are structurally - // identical (on purpose!), so there's no need to make a copy. - -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. - error = CallNPP_SetWindowProc(fCallbacks->setwindow, - &fNPP, - (NPWindow*) window); -#endif - - // XXX In the old code, we'd just ignore any errors coming - // back from the plugin's SetWindow(). Is this the correct - // behavior?!? - - if (error != NPERR_NO_ERROR) - printf("error in setwindow %d\n", error); - } - - return NS_OK; -} - -/* NOTE: the caller must free the stream listener */ - -NS_IMETHODIMP ns4xPluginInstance::NewStream(nsIPluginStreamListener** listener) -{ - nsISupports* stream = nsnull; - stream = (nsISupports *)(nsIPluginStreamListener *)new ns4xPluginStreamListener(this, nsnull); - - if(stream == nsnull) - return NS_ERROR_OUT_OF_MEMORY; - - nsresult res = stream->QueryInterface(kIPluginStreamListenerIID, (void**)listener); - - // If we didn't get the right interface, clean up - if (res != NS_OK) - delete stream; - - return res; -} - -nsresult ns4xPluginInstance::NewNotifyStream(nsIPluginStreamListener** listener, void* notifyData) -{ - *listener = new ns4xPluginStreamListener(this, notifyData); - return NS_OK; -} - -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"); - PRInt16 res = 0; - - if (fCallbacks->event) - { -#if !TARGET_CARBON -// pinkerton -// relies on routine descriptors, not present in carbon. We need to fix this. -#ifdef XP_MAC - res = CallNPP_HandleEventProc(fCallbacks->event, - &fNPP, - (void*) event->event); -#endif - -#ifdef XP_WIN //~~~ - NPEvent npEvent; - npEvent.event = event->event; - npEvent.wParam = event->wParam; - npEvent.lParam = event->lParam; - res = CallNPP_HandleEventProc(fCallbacks->event, - &fNPP, - (void*)&npEvent); -#endif - -#endif - - *handled = res; - } - - - return NS_OK; -} - -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; -} - -nsresult ns4xPluginInstance::GetNPP(NPP* aNPP) -{ - if(aNPP != nsnull) - *aNPP = &fNPP; - else - return NS_ERROR_NULL_POINTER; - - return NS_OK; -} - -nsresult ns4xPluginInstance::GetCallbacks(const NPPluginFuncs ** aCallbacks) -{ - if(aCallbacks != nsnull) - *aCallbacks = fCallbacks; - else - return NS_ERROR_NULL_POINTER; - - return NS_OK; -} - -nsresult ns4xPluginInstance :: SetWindowless(PRBool aWindowless) -{ - mWindowless = aWindowless; - return NS_OK; -} - -nsresult ns4xPluginInstance :: SetTransparent(PRBool aTransparent) -{ - mTransparent = aTransparent; - return NS_OK; -} +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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. + */ + +#include "ns4xPluginInstance.h" +#include "nsIPluginStreamListener.h" + +#include "prlog.h" +#include "prmem.h" +#include "nscore.h" + + +class ns4xPluginStreamListener : public nsIPluginStreamListener { + +public: + + NS_DECL_ISUPPORTS + + //////////////////////////////////////////////////////////////////////////// + // from nsIPluginStreamListener: + + NS_IMETHOD + OnStartBinding(nsIPluginStreamInfo* pluginInfo); + + NS_IMETHOD + OnDataAvailable(nsIPluginStreamInfo* pluginInfo, nsIInputStream* input, PRUint32 length); + + NS_IMETHOD + OnFileAvailable( nsIPluginStreamInfo* pluginInfo, const char* fileName); + + NS_IMETHOD + OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status); + + NS_IMETHOD + GetStreamType(nsPluginStreamType *result); + + //////////////////////////////////////////////////////////////////////////// + // ns4xPluginStreamListener specific methods: + + ns4xPluginStreamListener(nsIPluginInstance* inst, void* notifyData); + virtual ~ns4xPluginStreamListener(void); + +protected: + + void* mNotifyData; + ns4xPluginInstance* mInst; + NPStream mNPStream; + PRUint32 mPosition; + nsPluginStreamType mStreamType; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// ns4xPluginStreamListener Methods +//////////////////////////////////////////////////////////////////////////////// + +static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID); + +ns4xPluginStreamListener::ns4xPluginStreamListener(nsIPluginInstance* inst, void* notifyData) + : mNotifyData(notifyData) +{ + NS_INIT_REFCNT(); + mInst = (ns4xPluginInstance*) inst; + mPosition = 0; + + // Initialize the 4.x interface structure + memset(&mNPStream, 0, sizeof(mNPStream)); + + NS_IF_ADDREF(mInst); +} + +ns4xPluginStreamListener::~ns4xPluginStreamListener(void) +{ + NS_IF_RELEASE(mInst); +} + +NS_IMPL_ISUPPORTS(ns4xPluginStreamListener, kIPluginStreamListenerIID); + +NS_IMETHODIMP +ns4xPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo) +{ + + printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding()\n"); + NPP npp; + const NPPluginFuncs *callbacks; + PRBool seekable; + nsMIMEType contentType; + PRUint16 streamType = NP_NORMAL; + NPError error; + + mNPStream.ndata = (void*) this; + pluginInfo->GetURL(&mNPStream.url); + mNPStream.notifyData = mNotifyData; + + pluginInfo->GetLength((PRUint32*)&(mNPStream.end)); + pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified)); + pluginInfo->IsSeekable(&seekable); + pluginInfo->GetContentType(&contentType); + + mInst->GetCallbacks(&callbacks); + mInst->GetNPP(&npp); + + printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding() done GetNPP()\n"); +#if !TARGET_CARBON + printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding() about to call CallNPP_NewStreamProc: callbacks->newstream: %p\n", callbacks->newstream); +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + error = CallNPP_NewStreamProc(callbacks->newstream, + npp, + (char *)contentType, + &mNPStream, + seekable, + &streamType); + if(error != NPERR_NO_ERROR) + return NS_ERROR_FAILURE; +#endif + // translate the old 4x style stream type to the new one + switch(streamType) + { + case NP_NORMAL : mStreamType = nsPluginStreamType_Normal; break; + + case NP_ASFILEONLY : mStreamType = nsPluginStreamType_AsFileOnly; break; + + case NP_ASFILE : mStreamType = nsPluginStreamType_AsFile; break; + + case NP_SEEK : mStreamType = nsPluginStreamType_Seek; break; + + default: return NS_ERROR_FAILURE; + } + + printf("debug: edburns: ns4xPluginStreamListener::OnStartBinding() done switch\n"); + + return NS_OK; +} + +NS_IMETHODIMP +ns4xPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo, + nsIInputStream* input, + PRUint32 length) +{ + const NPPluginFuncs *callbacks; + NPP npp; + PRUint32 numtowrite = 0; + PRUint32 amountRead = 0; + PRInt32 writeCount = 0; + + pluginInfo->GetURL(&mNPStream.url); + pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified)); + + mInst->GetCallbacks(&callbacks); + mInst->GetNPP(&npp); + + if (callbacks->write == NULL || length == 0) + return NS_OK; // XXX ? + + // Get the data from the input stream + char* buffer = (char*) PR_Malloc(length); + if (buffer) + input->Read(buffer, length, &amountRead); + + // amountRead tells us how many bytes were put in the buffer + // WriteReady returns to us how many bytes the plugin is + // ready to handle - we have to keep calling WriteReady and + // Write until the buffer is empty + while (amountRead > 0) + { + if (callbacks->writeready != NULL) + { +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + numtowrite = CallNPP_WriteReadyProc(callbacks->writeready, + npp, + &mNPStream); +#endif + + if (numtowrite > amountRead) + numtowrite = amountRead; + } + else // if WriteReady is not supported by the plugin, just write the whole buffer + numtowrite = length; + + // if WriteReady returned 0, the plugin is not ready to handle the data, + // so just skip the Write until WriteReady returns a >0 value + if(numtowrite > 0) + { +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + writeCount = CallNPP_WriteProc(callbacks->write, + npp, + &mNPStream, + mPosition, + numtowrite, + (void *)buffer); + if(writeCount < 0) + return NS_ERROR_FAILURE; +#endif + amountRead -= numtowrite; + mPosition += numtowrite; + } + } + + return NS_OK; +} + +NS_IMETHODIMP +ns4xPluginStreamListener::OnFileAvailable(nsIPluginStreamInfo* pluginInfo, const char* fileName) +{ + const NPPluginFuncs *callbacks; + NPP npp; + + pluginInfo->GetURL(&mNPStream.url); + + mInst->GetCallbacks(&callbacks); + mInst->GetNPP(&npp); + + if (callbacks->asfile == NULL) + return NS_OK; + +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + CallNPP_StreamAsFileProc(callbacks->asfile, + npp, + &mNPStream, + fileName); +#endif + + return NS_OK; +} + +NS_IMETHODIMP +ns4xPluginStreamListener::OnStopBinding(nsIPluginStreamInfo* pluginInfo, nsresult status) +{ + const NPPluginFuncs *callbacks; + NPP npp; + NPError error; + + pluginInfo->GetURL(&mNPStream.url); + pluginInfo->GetLastModified((PRUint32*)&(mNPStream.lastmodified)); + + mInst->GetCallbacks(&callbacks); + mInst->GetNPP(&npp); + + if (callbacks->destroystream != NULL) + { + // XXX need to convert status to NPReason +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + error = CallNPP_DestroyStreamProc(callbacks->destroystream, + npp, + &mNPStream, + NPRES_DONE); + if(error != NPERR_NO_ERROR) + return NS_ERROR_FAILURE; +#endif + } + + // check to see if we have a call back + if (callbacks->urlnotify != NULL && mNotifyData != nsnull) + { +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + CallNPP_URLNotifyProc(callbacks->urlnotify, + npp, + mNPStream.url, + nsPluginReason_Done, + mNotifyData); +#endif + } + + return NS_OK; +} + +NS_IMETHODIMP +ns4xPluginStreamListener::GetStreamType(nsPluginStreamType *result) +{ + *result = mStreamType; + return NS_OK; +} + +ns4xPluginInstance :: ns4xPluginInstance(NPPluginFuncs* callbacks) + : fCallbacks(callbacks) +{ + NS_INIT_REFCNT(); + + NS_ASSERTION(fCallbacks != NULL, "null callbacks"); + + // Initialize the NPP structure. + + fNPP.pdata = NULL; + fNPP.ndata = this; + + fPeer = nsnull; + + mWindowless = PR_FALSE; + mTransparent = PR_FALSE; + mStarted = PR_FALSE; +} + + +ns4xPluginInstance :: ~ns4xPluginInstance(void) +{ + NS_RELEASE(fPeer); +} + + +//////////////////////////////////////////////////////////////////////// + +NS_IMPL_ADDREF(ns4xPluginInstance); +NS_IMPL_RELEASE(ns4xPluginInstance); + +static NS_DEFINE_IID(kIPluginInstanceIID, NS_IPLUGININSTANCE_IID); +static NS_DEFINE_IID(kIPluginTagInfoIID, NS_IPLUGINTAGINFO_IID); +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + +NS_IMETHODIMP ns4xPluginInstance :: QueryInterface(const nsIID& iid, void** instance) +{ + if (instance == NULL) + return NS_ERROR_NULL_POINTER; + + if (iid.Equals(kIPluginInstanceIID)) + { + *instance = (void *)(nsIPluginInstance *)this; + AddRef(); + return NS_OK; + } + + if (iid.Equals(kISupportsIID)) + { + *instance = (void *)(nsISupports *)this; + AddRef(); + return NS_OK; + } + + return NS_NOINTERFACE; +} + + +//////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP ns4xPluginInstance :: Initialize(nsIPluginInstancePeer* peer) +{ + return InitializePlugin(peer); +} + +NS_IMETHODIMP ns4xPluginInstance :: GetPeer(nsIPluginInstancePeer* *resultingPeer) +{ + NS_ADDREF(fPeer); + *resultingPeer = fPeer; + + return NS_OK; +} + +NS_IMETHODIMP ns4xPluginInstance::Start(void) +{ + printf("instance start called\n"); + if(mStarted) + return NS_OK; + else + return InitializePlugin(fPeer); +} + +NS_IMETHODIMP ns4xPluginInstance::Stop(void) +{ + NPError error; + + printf("instance stop/destroy called\n"); + if (fCallbacks->destroy == NULL) + return NS_ERROR_FAILURE; // XXX right error? + + NPSavedData *sdata; + +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + error = (nsresult)CallNPP_DestroyProc(fCallbacks->destroy, + &fNPP, &sdata); // saved data +#endif + + 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); + +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + error = CallNPP_NewProc(fCallbacks->newp, + (char *)mimetype, + &fNPP, + (PRUint16)mode, + count, + (char**)names, + (char**)values, + NULL); // saved data +#endif + + if(error != NPERR_NO_ERROR) + rv = NS_ERROR_FAILURE; + + mStarted = PR_TRUE; + + return rv; +} + +NS_IMETHODIMP ns4xPluginInstance::Destroy(void) +{ + printf("instance destroy called\n"); + // destruction is handled in the Stop call + return NS_OK; +} + +NS_IMETHODIMP ns4xPluginInstance::SetWindow(nsPluginWindow* window) +{ + // XXX 4.x plugins don't want a SetWindow(NULL). + + if (window == NULL || mStarted == PR_FALSE) + return NS_OK; + + NPError error; + + if (fCallbacks->setwindow) + { + // XXX Turns out that NPPluginWindow and NPWindow are structurally + // identical (on purpose!), so there's no need to make a copy. + +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. + error = CallNPP_SetWindowProc(fCallbacks->setwindow, + &fNPP, + (NPWindow*) window); +#endif + + // XXX In the old code, we'd just ignore any errors coming + // back from the plugin's SetWindow(). Is this the correct + // behavior?!? + + if (error != NPERR_NO_ERROR) + printf("error in setwindow %d\n", error); + } + + return NS_OK; +} + +/* NOTE: the caller must free the stream listener */ + +NS_IMETHODIMP ns4xPluginInstance::NewStream(nsIPluginStreamListener** listener) +{ + nsISupports* stream = nsnull; + stream = (nsISupports *)(nsIPluginStreamListener *)new ns4xPluginStreamListener(this, nsnull); + + if(stream == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + nsresult res = stream->QueryInterface(kIPluginStreamListenerIID, (void**)listener); + + // If we didn't get the right interface, clean up + if (res != NS_OK) + delete stream; + + return res; +} + +nsresult ns4xPluginInstance::NewNotifyStream(nsIPluginStreamListener** listener, void* notifyData) +{ + *listener = new ns4xPluginStreamListener(this, notifyData); + return NS_OK; +} + +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"); + PRInt16 res = 0; + + if (fCallbacks->event) + { +#if !TARGET_CARBON +// pinkerton +// relies on routine descriptors, not present in carbon. We need to fix this. +#ifdef XP_MAC + res = CallNPP_HandleEventProc(fCallbacks->event, + &fNPP, + (void*) event->event); +#endif + +#ifdef XP_WIN //~~~ + NPEvent npEvent; + npEvent.event = event->event; + npEvent.wParam = event->wParam; + npEvent.lParam = event->lParam; + res = CallNPP_HandleEventProc(fCallbacks->event, + &fNPP, + (void*)&npEvent); +#endif + +#endif + + *handled = res; + } + + + return NS_OK; +} + +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; +} + +nsresult ns4xPluginInstance::GetNPP(NPP* aNPP) +{ + if(aNPP != nsnull) + *aNPP = &fNPP; + else + return NS_ERROR_NULL_POINTER; + + return NS_OK; +} + +nsresult ns4xPluginInstance::GetCallbacks(const NPPluginFuncs ** aCallbacks) +{ + if(aCallbacks != nsnull) + *aCallbacks = fCallbacks; + else + return NS_ERROR_NULL_POINTER; + + return NS_OK; +} + +nsresult ns4xPluginInstance :: SetWindowless(PRBool aWindowless) +{ + mWindowless = aWindowless; + return NS_OK; +} + +nsresult ns4xPluginInstance :: SetTransparent(PRBool aTransparent) +{ + mTransparent = aTransparent; + return NS_OK; +} diff --git a/modules/plugin/nglsrc/nsPluginsDir.h b/modules/plugin/nglsrc/nsPluginsDir.h index e8ae6c556747..5cc865d59128 100644 --- a/modules/plugin/nglsrc/nsPluginsDir.h +++ b/modules/plugin/nglsrc/nsPluginsDir.h @@ -1,90 +1,90 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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 nsPluginsDir_h___ -#define nsPluginsDir_h___ - -#include "nsError.h" -#include "nsFileSpec.h" - -/** - * Provides a cross-platform way to obtain the location of the plugins - * directory. Once constructed, can be used with nsDirectoryIterator to - * scan the plugins directory. An nsPluginFileSpec can be constructed from the - * nsFileSpec returned by the iterator. - */ -class nsPluginsDir : public nsFileSpec { -public: - /** - * Locates the plugins directory in a platform-dependent manner. - */ - nsPluginsDir(); - virtual ~nsPluginsDir(); - - /** - * Determines whether or not the given file is actually a plugin file. - */ - PRBool IsPluginFile(const nsFileSpec& fileSpec); -}; - -struct PRLibrary; - -struct nsPluginInfo { - PRUint32 fPluginInfoSize; // indicates how large the structure is currently. - char* fName; // name of the plugin - char* fDescription; // etc. - char* fMimeType; - char* fMimeDescription; - char* fExtensions; - PRUint32 fVariantCount; - char** fMimeTypeArray; - char** fMimeDescriptionArray; - char** fExtensionArray; - char* fFileName; -}; - -/** - * Provides cross-platform access to a plugin file. Deals with reading - * properties from the plugin file, and loading the plugin's shared - * library. Insulates core nsIPluginHost implementations from these - * details. - */ -class nsPluginFile : public nsFileSpec { - PRLibrary* pLibrary; -public: - /** - * If spec corresponds to a valid plugin file, constructs a reference - * to a plugin file on disk. Plugins are typically located using the - * nsPluginsDir class. - */ - nsPluginFile(const nsFileSpec& spec); - virtual ~nsPluginFile(); - - /** - * Loads the plugin into memory using NSPR's shared-library loading - * mechanism. Handles platform differences in loading shared libraries. - */ - nsresult LoadPlugin(PRLibrary* &outLibrary); - - /** - * Obtains all of the information currently available for this plugin. - */ - nsresult GetPluginInfo(nsPluginInfo &outPluginInfo); -}; - -#endif /* nsPluginsDir_h___ */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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 nsPluginsDir_h___ +#define nsPluginsDir_h___ + +#include "nsError.h" +#include "nsFileSpec.h" + +/** + * Provides a cross-platform way to obtain the location of the plugins + * directory. Once constructed, can be used with nsDirectoryIterator to + * scan the plugins directory. An nsPluginFileSpec can be constructed from the + * nsFileSpec returned by the iterator. + */ +class nsPluginsDir : public nsFileSpec { +public: + /** + * Locates the plugins directory in a platform-dependent manner. + */ + nsPluginsDir(); + virtual ~nsPluginsDir(); + + /** + * Determines whether or not the given file is actually a plugin file. + */ + PRBool IsPluginFile(const nsFileSpec& fileSpec); +}; + +struct PRLibrary; + +struct nsPluginInfo { + PRUint32 fPluginInfoSize; // indicates how large the structure is currently. + char* fName; // name of the plugin + char* fDescription; // etc. + char* fMimeType; + char* fMimeDescription; + char* fExtensions; + PRUint32 fVariantCount; + char** fMimeTypeArray; + char** fMimeDescriptionArray; + char** fExtensionArray; + char* fFileName; +}; + +/** + * Provides cross-platform access to a plugin file. Deals with reading + * properties from the plugin file, and loading the plugin's shared + * library. Insulates core nsIPluginHost implementations from these + * details. + */ +class nsPluginFile : public nsFileSpec { + PRLibrary* pLibrary; +public: + /** + * If spec corresponds to a valid plugin file, constructs a reference + * to a plugin file on disk. Plugins are typically located using the + * nsPluginsDir class. + */ + nsPluginFile(const nsFileSpec& spec); + virtual ~nsPluginFile(); + + /** + * Loads the plugin into memory using NSPR's shared-library loading + * mechanism. Handles platform differences in loading shared libraries. + */ + nsresult LoadPlugin(PRLibrary* &outLibrary); + + /** + * Obtains all of the information currently available for this plugin. + */ + nsresult GetPluginInfo(nsPluginInfo &outPluginInfo); +}; + +#endif /* nsPluginsDir_h___ */ diff --git a/modules/plugin/nglsrc/nsPluginsDirUNIX.cpp b/modules/plugin/nglsrc/nsPluginsDirUNIX.cpp index f563caecf6d6..9bcb4980922e 100644 --- a/modules/plugin/nglsrc/nsPluginsDirUNIX.cpp +++ b/modules/plugin/nglsrc/nsPluginsDirUNIX.cpp @@ -1,247 +1,247 @@ -/* -*- 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. - */ - -/* - nsPluginsDirUNIX.cpp - - UNIX implementation of the nsPluginsDir/nsPluginsFile classes. - - by Alex Musil - */ - -#include "nsPluginsDir.h" -#include "prlink.h" -#include "plstr.h" -#include "prmem.h" - -#include "nsSpecialSystemDirectory.h" - -/* Local helper functions */ - -static char* GetFileName(const char* pathname) -{ - const char* filename = nsnull; - - // this is most likely a path, so skip to the filename - filename = PL_strrchr(pathname, '/'); - if(filename) - ++filename; - else - filename = pathname; - - return PL_strdup(filename); -} - -static PRUint32 CalculateVariantCount(char* mimeTypes) -{ - PRUint32 variants = 0; - char* index = mimeTypes; - while (*index) - { - if (*index == ';') - variants++; - - ++index; - } - return variants; -} - -static char** MakeStringArray(PRUint32 variants, char* data) -{ - char** buffer = NULL; - char* index = data; - PRUint32 count = 0; - - buffer = (char **)PR_Malloc(variants * sizeof(char *)); - buffer[count++] = index; - - while (*index && count/plugins and ~/.mozilla/plugins. There - // doesn't seem to be any way to do this in the current nsPluginsDir code, which is disheartening. - // - - // use MOZILLA_FIVE_HOME/plugins - - nsSpecialSystemDirectory sysdir(nsSpecialSystemDirectory::OS_CurrentProcessDirectory); - sysdir += "plugins"; - const char *pluginsDir = sysdir.GetCString(); // native path - if (pluginsDir != NULL) - { - const char* allocPath; - - allocPath = PL_strdup(pluginsDir); - *(nsFileSpec*)this = allocPath; - } -} - -nsPluginsDir::~nsPluginsDir() -{ - // do nothing -} - -PRBool nsPluginsDir::IsPluginFile(const nsFileSpec& fileSpec) -{ - const char* pathname = fileSpec.GetCString(); - -#ifdef NS_DEBUG - printf("IsPluginFile(%s)\n", pathname); -#endif - - return PR_TRUE; -} - -/////////////////////////////////////////////////////////////////////////// - -/* nsPluginFile implementation */ - -nsPluginFile::nsPluginFile(const nsFileSpec& spec) - : nsFileSpec(spec) -{ - // nada -} - -nsPluginFile::~nsPluginFile() -{ - // nada -} - -/** - * Loads the plugin into memory using NSPR's shared-library loading - * mechanism. Handles platform differences in loading shared libraries. - */ -nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary) -{ - const char* path = this->GetCString(); - pLibrary = outLibrary = PR_LoadLibrary(path); - -#ifdef NS_DEBUG - printf("LoadPlugin() %s returned %lx\n",path,pLibrary); -#endif - - return NS_OK; -} - -typedef char* (*UNIX_Plugin_GetMIMEDescription)(); - - -/** - * Obtains all of the information currently available for this plugin. - */ -nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info) -{ - const char *path = this->GetCString(); - char *mimedescr,*mdesc,*start,*nexttoc,*mtype,*exten,*descr; - int i,num; - - UNIX_Plugin_GetMIMEDescription procedure = nsnull; - mimedescr=""; - - if(procedure = (UNIX_Plugin_GetMIMEDescription)PR_FindSymbol(pLibrary,"NP_GetMIMEDescription")) { - mimedescr = procedure(); - } else { -#ifdef NS_DEBUG - printf("Cannot get plugin info: no GetMIMEDescription procedure!\n"); -#endif - return NS_ERROR_FAILURE; - } - - info.fName = GetFileName(path); - -#ifdef NS_DEBUG - printf("GetMIMEDescription() %lx returned \"%s\"\n",procedure,mimedescr); -#endif - - // copy string - - mdesc = (char *)PR_Malloc(strlen(mimedescr)+1); - strcpy(mdesc,mimedescr); - num=CalculateVariantCount(mimedescr)+1; - info.fVariantCount = num; - - info.fMimeTypeArray =(char **)PR_Malloc(num * sizeof(char *)); - info.fMimeDescriptionArray =(char **)PR_Malloc(num * sizeof(char *)); - info.fExtensionArray =(char **)PR_Malloc(num * sizeof(char *)); - - start=mdesc; - for(i=0;i/plugins and ~/.mozilla/plugins. There + // doesn't seem to be any way to do this in the current nsPluginsDir code, which is disheartening. + // + + // use MOZILLA_FIVE_HOME/plugins + + nsSpecialSystemDirectory sysdir(nsSpecialSystemDirectory::OS_CurrentProcessDirectory); + sysdir += "plugins"; + const char *pluginsDir = sysdir.GetCString(); // native path + if (pluginsDir != NULL) + { + const char* allocPath; + + allocPath = PL_strdup(pluginsDir); + *(nsFileSpec*)this = allocPath; + } +} + +nsPluginsDir::~nsPluginsDir() +{ + // do nothing +} + +PRBool nsPluginsDir::IsPluginFile(const nsFileSpec& fileSpec) +{ + const char* pathname = fileSpec.GetCString(); + +#ifdef NS_DEBUG + printf("IsPluginFile(%s)\n", pathname); +#endif + + return PR_TRUE; +} + +/////////////////////////////////////////////////////////////////////////// + +/* nsPluginFile implementation */ + +nsPluginFile::nsPluginFile(const nsFileSpec& spec) + : nsFileSpec(spec) +{ + // nada +} + +nsPluginFile::~nsPluginFile() +{ + // nada +} + +/** + * Loads the plugin into memory using NSPR's shared-library loading + * mechanism. Handles platform differences in loading shared libraries. + */ +nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary) +{ + const char* path = this->GetCString(); + pLibrary = outLibrary = PR_LoadLibrary(path); + +#ifdef NS_DEBUG + printf("LoadPlugin() %s returned %lx\n",path,pLibrary); +#endif + + return NS_OK; +} + +typedef char* (*UNIX_Plugin_GetMIMEDescription)(); + + +/** + * Obtains all of the information currently available for this plugin. + */ +nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info) +{ + const char *path = this->GetCString(); + char *mimedescr,*mdesc,*start,*nexttoc,*mtype,*exten,*descr; + int i,num; + + UNIX_Plugin_GetMIMEDescription procedure = nsnull; + mimedescr=""; + + if(procedure = (UNIX_Plugin_GetMIMEDescription)PR_FindSymbol(pLibrary,"NP_GetMIMEDescription")) { + mimedescr = procedure(); + } else { +#ifdef NS_DEBUG + printf("Cannot get plugin info: no GetMIMEDescription procedure!\n"); +#endif + return NS_ERROR_FAILURE; + } + + info.fName = GetFileName(path); + +#ifdef NS_DEBUG + printf("GetMIMEDescription() %lx returned \"%s\"\n",procedure,mimedescr); +#endif + + // copy string + + mdesc = (char *)PR_Malloc(strlen(mimedescr)+1); + strcpy(mdesc,mimedescr); + num=CalculateVariantCount(mimedescr)+1; + info.fVariantCount = num; + + info.fMimeTypeArray =(char **)PR_Malloc(num * sizeof(char *)); + info.fMimeDescriptionArray =(char **)PR_Malloc(num * sizeof(char *)); + info.fExtensionArray =(char **)PR_Malloc(num * sizeof(char *)); + + start=mdesc; + for(i=0;i