dougt%netscape.com fed2927b2c Create a new xpcom obsolete library (and component library).
Moved nsFileSpec and related classes into this obsolete library.
  Moved nsRegistry and related libreg functionality into the obsolete library.

Updated many callers using the obsolete nsFile spec to use nsIFile and Necko to do file IO.

Combined the following DLLs (source -> dest)
  uriloader -> docshell
  shistory -> docshell
  jsurl -> jsdom
  gkview -> gklayout

Moved nsAdapterEnumerator out of xpcom/ds and into mailnews, since they're the only consumer

Modifed the xpt_link tool so that you can specify a “only include” cid list that can mask CID’s that you are not interested in.

Added build options:
Prevent the building of xpinstall (--disable-xpinstall)
Prevent the building js component loader (--disable-jsloader)
A build option to only build a single profile (--enable-single-profile)
A build flag to only built the required xpfe components (--disable-xpfe-components).

Removal or hiding of unused functions and classes including nsEscape*, nsDequeIterator, nsRecyclingAllocatorImpl, nsDiscriminatedUnion, nsOpaqueKey, nsCRT::strlen, NS_NewCommandLineService

Bug 194240, r/sr = darin, alec.


git-svn-id: svn://10.0.0.236/trunk@139480 18797224-902f-48f8-a5cc-f745e15eee43
2003-03-15 01:04:32 +00:00

1515 lines
45 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// TODO: Implement Java callbacks
#include "prtypes.h"
#include "ns4xPlugin.h"
#include "ns4xPluginInstance.h"
#include "ns4xPluginStreamListener.h"
#include "nsIServiceManager.h"
#include "nsIMemory.h"
#include "nsIPluginStreamListener.h"
#include "nsPluginsDir.h"
#include "nsPluginSafety.h"
#include "nsIPref.h"
#include "nsPluginLogging.h"
#include "nsIPluginInstancePeer2.h"
#include "nsIJSContextStack.h"
#include "nsPIPluginInstancePeer.h"
#include "nsIDOMElement.h"
#include "nsIDOMDocument.h"
#include "nsIDOMWindow.h"
#include "nsIDocument.h"
#include "nsIScriptGlobalObject.h"
#if defined(XP_MAC) || defined(XP_MACOSX)
#include <Resources.h>
#endif
//needed for nppdf plugin
#ifdef MOZ_WIDGET_GTK
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include "gtkxtbin.h"
#endif
#ifdef MOZ_WIDGET_GTK2
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include "gtk2xtbin.h"
#endif
// POST/GET stream type
enum eNPPStreamTypeInternal {
eNPPStreamTypeInternal_Get,
eNPPStreamTypeInternal_Post
};
////////////////////////////////////////////////////////////////////////
// CID's && IID's
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
static NS_DEFINE_IID(kCPluginManagerCID, NS_PLUGINMANAGER_CID);
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(kMemoryCID, NS_MEMORY_CID);
static NS_DEFINE_IID(kIMemoryIID, NS_IMEMORY_IID);
static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID);
PR_BEGIN_EXTERN_C
////////////////////////////////////////////////////////////////////////
// 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
PR_END_EXTERN_C
#ifdef XP_MACOSX
static void* TV2FP(void *tvp)
{
static uint32 glue[6] = { 0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420 };
uint32* newGlue = NULL;
if (tvp != NULL) {
newGlue = (uint32*) malloc(sizeof(glue));
if (newGlue != NULL) {
memcpy(newGlue, glue, sizeof(glue));
newGlue[0] |= ((UInt32)tvp >> 16);
newGlue[1] |= ((UInt32)tvp & 0xFFFF);
MakeDataExecutable(newGlue, sizeof(glue));
}
}
return newGlue;
}
static void* FP2TV(void *fp)
{
void **newGlue = NULL;
if (fp != NULL) {
newGlue = (void**) malloc(2 * sizeof(void *));
if (newGlue != NULL) {
newGlue[0] = fp;
newGlue[1] = NULL;
}
}
return newGlue;
}
#else
#define TV2FP(f) (f)
#define FP2TV(f) (f)
#endif /* XP_MACOSX */
////////////////////////////////////////////////////////////////////////
// Globals
NPNetscapeFuncs ns4xPlugin::CALLBACKS;
static nsIServiceManagerObsolete* gServiceMgr = nsnull;
static nsIMemory* gMalloc = nsnull;
////////////////////////////////////////////////////////////////////////
void
ns4xPlugin::CheckClassInitialized(void)
{
static PRBool initialized = FALSE;
if (initialized)
return;
// 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;
CALLBACKS.geturl = NewNPN_GetURLProc(FP2TV(_geturl));
CALLBACKS.posturl = NewNPN_PostURLProc(FP2TV(_posturl));
CALLBACKS.requestread = NewNPN_RequestReadProc(FP2TV(_requestread));
CALLBACKS.newstream = NewNPN_NewStreamProc(FP2TV(_newstream));
CALLBACKS.write = NewNPN_WriteProc(FP2TV(_write));
CALLBACKS.destroystream = NewNPN_DestroyStreamProc(FP2TV(_destroystream));
CALLBACKS.status = NewNPN_StatusProc(FP2TV(_status));
CALLBACKS.uagent = NewNPN_UserAgentProc(FP2TV(_useragent));
CALLBACKS.memalloc = NewNPN_MemAllocProc(FP2TV(_memalloc));
CALLBACKS.memfree = NewNPN_MemFreeProc(FP2TV(_memfree));
CALLBACKS.memflush = NewNPN_MemFlushProc(FP2TV(_memflush));
CALLBACKS.reloadplugins = NewNPN_ReloadPluginsProc(FP2TV(_reloadplugins));
CALLBACKS.getJavaEnv = NewNPN_GetJavaEnvProc(FP2TV(_getJavaEnv));
CALLBACKS.getJavaPeer = NewNPN_GetJavaPeerProc(FP2TV(_getJavaPeer));
CALLBACKS.geturlnotify = NewNPN_GetURLNotifyProc(FP2TV(_geturlnotify));
CALLBACKS.posturlnotify = NewNPN_PostURLNotifyProc(FP2TV(_posturlnotify));
CALLBACKS.getvalue = NewNPN_GetValueProc(FP2TV(_getvalue));
CALLBACKS.setvalue = NewNPN_SetValueProc(FP2TV(_setvalue));
CALLBACKS.invalidaterect = NewNPN_InvalidateRectProc(FP2TV(_invalidaterect));
CALLBACKS.invalidateregion = NewNPN_InvalidateRegionProc(FP2TV(_invalidateregion));
CALLBACKS.forceredraw = NewNPN_ForceRedrawProc(FP2TV(_forceredraw));
initialized = TRUE;
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,("NPN callbacks initialized\n"));
}
////////////////////////////////////////////////////////////////////////
// nsISupports stuff
NS_IMPL_ISUPPORTS2(ns4xPlugin, nsIPlugin, nsIFactory);
ns4xPlugin::ns4xPlugin(NPPluginFuncs* callbacks, PRLibrary* aLibrary, NP_PLUGINSHUTDOWN aShutdown, nsIServiceManagerObsolete* serviceMgr)
{
memset((void*) &fCallbacks, 0, sizeof(fCallbacks));
gServiceMgr = serviceMgr;
fLibrary = nsnull;
#if defined(XP_WIN)
// On Windows (and Mac) we need to keep a direct reference to the fCallbacks and NOT
// just copy the struct. See Bugzilla 85334
NP_GETENTRYPOINTS pfnGetEntryPoints =
(NP_GETENTRYPOINTS)PR_FindSymbol(aLibrary, "NP_GetEntryPoints");
if (!pfnGetEntryPoints)
return;
fCallbacks.size = sizeof(fCallbacks);
nsresult result = pfnGetEntryPoints(&fCallbacks);
NS_ASSERTION( NS_OK == result,"Failed to get callbacks");
NS_ASSERTION(HIBYTE(fCallbacks.version) >= NP_VERSION_MAJOR, "callback version is less than NP version");
fShutdownEntry = (NP_PLUGINSHUTDOWN)PR_FindSymbol(aLibrary, "NP_Shutdown");
#elif defined(XP_MAC) && !TARGET_CARBON
// get the main entry point
NP_MAIN pfnMain = (NP_MAIN) PR_FindSymbol(aLibrary, "mainRD");
if(pfnMain == NULL)
return;
// call into the entry point
NPError error;
NS_TRY_SAFE_CALL_RETURN(error, CallNPP_MainEntryProc(pfnMain,
&(ns4xPlugin::CALLBACKS),
&fCallbacks,
&fShutdownEntry), aLibrary, nsnull);
NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPP MainEntryProc called, return=%d\n",error));
if(error != NPERR_NO_ERROR || ((fCallbacks.version >> 8) < NP_VERSION_MAJOR))
return;
#elif defined(XP_MACOSX) || (defined(XP_MAC) && TARGET_CARBON)
// call into the entry point
NP_MAIN pfnMain = (NP_MAIN) PR_FindSymbol(aLibrary, "main");
if(pfnMain == NULL)
return;
NPP_ShutdownUPP pfnShutdown;
NPPluginFuncs np_callbacks;
memset((void*) &np_callbacks, 0, sizeof(np_callbacks));
np_callbacks.size = sizeof(np_callbacks);
NPError error;
NS_TRY_SAFE_CALL_RETURN(error, CallNPP_MainEntryProc(pfnMain,
&(ns4xPlugin::CALLBACKS),
&np_callbacks,
&pfnShutdown), aLibrary, nsnull);
NPP_PLUGIN_LOG(PLUGIN_LOG_BASIC, ("NPP MainEntryProc called: return=%d\n",error));
if(error != NPERR_NO_ERROR)
return;
// version is a uint16 so cast to int to avoid an invalid
// comparison due to limited range of the data type
int cb_version = np_callbacks.version;
if ((cb_version >> 8) < NP_VERSION_MAJOR)
return;
// wrap all plugin entry points tvectors as mach-o callable function pointers.
fCallbacks.size = sizeof(fCallbacks);
fCallbacks.version = np_callbacks.version;
fCallbacks.newp = (NPP_NewUPP) TV2FP(np_callbacks.newp);
fCallbacks.destroy = (NPP_DestroyUPP) TV2FP(np_callbacks.destroy);
fCallbacks.setwindow = (NPP_SetWindowUPP) TV2FP(np_callbacks.setwindow);
fCallbacks.newstream = (NPP_NewStreamUPP) TV2FP(np_callbacks.newstream);
fCallbacks.destroystream = (NPP_DestroyStreamUPP) TV2FP(np_callbacks.destroystream);
fCallbacks.asfile = (NPP_StreamAsFileUPP) TV2FP(np_callbacks.asfile);
fCallbacks.writeready = (NPP_WriteReadyUPP) TV2FP(np_callbacks.writeready);
fCallbacks.write = (NPP_WriteUPP) TV2FP(np_callbacks.write);
fCallbacks.print = (NPP_PrintUPP) TV2FP(np_callbacks.print);
fCallbacks.event = (NPP_HandleEventUPP) TV2FP(np_callbacks.event);
fCallbacks.urlnotify = (NPP_URLNotifyUPP) TV2FP(np_callbacks.urlnotify);
fCallbacks.getvalue = (NPP_GetValueUPP) TV2FP(np_callbacks.getvalue);
fCallbacks.setvalue = (NPP_SetValueUPP) TV2FP(np_callbacks.setvalue);
fShutdownEntry = (NP_PLUGINSHUTDOWN) TV2FP(pfnShutdown);
#else // for everyone else
memcpy((void*) &fCallbacks, (void*) callbacks, sizeof(fCallbacks));
fShutdownEntry = aShutdown;
#endif
fLibrary = aLibrary;
}
////////////////////////////////////////////////////////////////////////
ns4xPlugin::~ns4xPlugin(void)
{
//reset the callbacks list
#if defined(XP_MACOSX)
// release all wrapped plugin entry points.
if (fCallbacks.newp)
free(fCallbacks.newp);
if (fCallbacks.destroy)
free(fCallbacks.destroy);
if (fCallbacks.setwindow)
free(fCallbacks.setwindow);
if (fCallbacks.newstream)
free(fCallbacks.newstream);
if (fCallbacks.asfile)
free(fCallbacks.asfile);
if (fCallbacks.writeready)
free(fCallbacks.writeready);
if (fCallbacks.write)
free(fCallbacks.write);
if (fCallbacks.print)
free(fCallbacks.print);
if (fCallbacks.event)
free(fCallbacks.event);
if (fCallbacks.urlnotify)
free(fCallbacks.urlnotify);
if (fCallbacks.getvalue)
free(fCallbacks.getvalue);
if (fCallbacks.setvalue)
free(fCallbacks.setvalue);
#endif
memset((void*) &fCallbacks, 0, sizeof(fCallbacks));
}
////////////////////////////////////////////////////////////////////////
void ns4xPlugin::ReleaseStatics()
{
NS_IF_RELEASE(gMalloc);
}
#if defined(XP_MAC) || defined(XP_MACOSX)
////////////////////////////////////////////////////////////////////////
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(nsIServiceManagerObsolete* aServiceMgr,
const char* aFileName,
const char* aFullPath,
PRLibrary* aLibrary,
nsIPlugin** aResult)
{
CheckClassInitialized();
// set up the MemAllocator service now because it might be used by the plugin
if (aServiceMgr != nsnull) {
if (nsnull == gMalloc)
aServiceMgr->GetService(kMemoryCID, kIMemoryIID, (nsISupports**)&gMalloc);
}
#if defined(XP_UNIX) && !defined(XP_MACOSX)
ns4xPlugin *plptr;
NPPluginFuncs callbacks;
memset((void*) &callbacks, 0, sizeof(callbacks));
callbacks.size = sizeof(callbacks);
NP_PLUGINSHUTDOWN pfnShutdown = (NP_PLUGINSHUTDOWN)PR_FindSymbol(aLibrary, "NP_Shutdown");
// create the new plugin handler
*aResult = plptr = new ns4xPlugin(&callbacks, aLibrary, pfnShutdown, aServiceMgr);
if (*aResult == NULL)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
if (!aFileName) //do not call NP_Initialize in this case, bug 74938
return NS_OK;
// 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(aLibrary, "NP_Initialize");
if (pfnInitialize == NULL)
return NS_ERROR_UNEXPECTED; // XXX Right error?
if (pfnInitialize(&(ns4xPlugin::CALLBACKS),&callbacks) != NS_OK)
return NS_ERROR_UNEXPECTED;
// now copy function table back to ns4xPlugin instance
memcpy((void*) &(plptr->fCallbacks), (void*)&callbacks, sizeof(callbacks));
#endif
#ifdef XP_WIN
// Note: on Windows, we must use the fCallback because plugins may change
// the function table. The Shockwave installer makes changes in the table while running
*aResult = new ns4xPlugin(nsnull, aLibrary, nsnull, aServiceMgr);
if (*aResult == NULL)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
// 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
if (NS_FAILED((*aResult)->Initialize())) {
NS_RELEASE(*aResult);
return NS_ERROR_FAILURE;
}
// 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(aLibrary, "NP_Initialize");
if (!pfnInitialize)
pfnInitialize = (NP_PLUGININIT)PR_FindSymbol(aLibrary, "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_OS2
// XXX Do we need to do this on OS/2 or can we look more like Windows?
NP_GETENTRYPOINTS pfnGetEntryPoints = (NP_GETENTRYPOINTS)PR_FindSymbol(aLibrary, "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
if (HIBYTE(callbacks.version) < NP_VERSION_MAJOR)
return NS_ERROR_FAILURE;
NP_PLUGINSHUTDOWN pfnShutdown = (NP_PLUGINSHUTDOWN)PR_FindSymbol(aLibrary, "NP_Shutdown");
// create the new plugin handler
*aResult = new ns4xPlugin(&callbacks, aLibrary, pfnShutdown, aServiceMgr);
if (*aResult == NULL)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
// 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
if (NS_FAILED((*aResult)->Initialize())) {
NS_RELEASE(*aResult);
return NS_ERROR_FAILURE;
}
// 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(aLibrary, "NP_Initialize");
if (!pfnInitialize)
pfnInitialize = (NP_PLUGININIT)PR_FindSymbol(aLibrary, "NP_PluginInit");
if (pfnInitialize == NULL)
return NS_ERROR_UNEXPECTED; // XXX Right error?
//Fixes problem where the OS/2 native multimedia plugins weren't working
// on mozilla though did work on 4.x. Problem is that they expect the
// current working directory to be the plugins dir. Since these plugins
// are no longer maintained and they represent the majority of the OS/2
// plugin contingency, we'll have to make them work here.
#define MAP_DISKNUM_TO_LETTER(n) ('A' + (n - 1))
#define MAP_LETTER_TO_DISKNUM(c) (toupper(c)-'A'+1)
unsigned long origDiskNum, pluginDiskNum, logicalDisk;
char pluginPath[CCHMAXPATH], origPath[CCHMAXPATH];
strcpy(pluginPath, aFileName);
char* slash = strrchr(pluginPath, '\\');
*slash = '\0';
DosQueryCurrentDisk( &origDiskNum, &logicalDisk );
pluginDiskNum = MAP_LETTER_TO_DISKNUM(pluginPath[0]);
origPath[0] = MAP_DISKNUM_TO_LETTER(origDiskNum);
origPath[1] = ':';
origPath[2] = '\\';
ULONG len = CCHMAXPATH-3;
APIRET rc = DosQueryCurrentDir(0, &origPath[3], &len);
NS_ASSERTION(NO_ERROR == rc,"DosQueryCurrentDir failed");
BOOL bChangedDir = FALSE;
BOOL bChangedDisk = FALSE;
if (pluginDiskNum != origDiskNum) {
rc = DosSetDefaultDisk(pluginDiskNum);
NS_ASSERTION(NO_ERROR == rc,"DosSetDefaultDisk failed");
bChangedDisk = TRUE;
}
if (stricmp(origPath, pluginPath) != 0) {
rc = DosSetCurrentDir(pluginPath);
NS_ASSERTION(NO_ERROR == rc,"DosSetCurrentDir failed");
bChangedDir = TRUE;
}
nsresult rv = pfnInitialize(&(ns4xPlugin::CALLBACKS));
if (bChangedDisk) {
rc= DosSetDefaultDisk(origDiskNum);
NS_ASSERTION(NO_ERROR == rc,"DosSetDefaultDisk failed");
}
if (bChangedDir) {
rc = DosSetCurrentDir(origPath);
NS_ASSERTION(NO_ERROR == rc,"DosSetCurrentDir failed");
}
if (!NS_SUCCEEDED(rv)) {
return NS_ERROR_UNEXPECTED;
}
#endif
#if defined(XP_MAC) || defined(XP_MACOSX)
short appRefNum = ::CurResFile();
short pluginRefNum;
nsCOMPtr<nsILocalFile> pluginPath;
NS_NewNativeLocalFile(nsDependentCString(aFullPath), PR_TRUE,
getter_AddRefs(pluginPath));
nsPluginFile pluginFile(pluginPath);
pluginRefNum = pluginFile.OpenPluginResource();
if (pluginRefNum == -1)
return NS_ERROR_FAILURE;
ns4xPlugin* plugin = new ns4xPlugin(nsnull, aLibrary, nsnull, aServiceMgr);
if(plugin == NULL)
return NS_ERROR_OUT_OF_MEMORY;
::UseResFile(appRefNum);
*aResult = plugin;
NS_ADDREF(*aResult);
if (NS_FAILED((*aResult)->Initialize())) {
NS_RELEASE(*aResult);
return NS_ERROR_FAILURE;
}
plugin->SetPluginRefNum(pluginRefNum);
#endif // XP_MAC || XP_MACOSX
#ifdef XP_BEOS
// I just copied UNIX version.
// Makoto Hamanaka <VYA04230@nifty.com>
ns4xPlugin *plptr;
NPPluginFuncs callbacks;
memset((void*) &callbacks, 0, sizeof(callbacks));
callbacks.size = sizeof(callbacks);
NP_PLUGINSHUTDOWN pfnShutdown = (NP_PLUGINSHUTDOWN)PR_FindSymbol(aLibrary, "NP_Shutdown");
// create the new plugin handler
*aResult = plptr = new ns4xPlugin(&callbacks, aLibrary, pfnShutdown, aServiceMgr);
if (*aResult == NULL)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
// 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(aLibrary, "NP_Initialize");
if (pfnInitialize == NULL)
return NS_ERROR_FAILURE;
if (pfnInitialize(&(ns4xPlugin::CALLBACKS),&callbacks) != NS_OK)
return NS_ERROR_FAILURE;
// now copy function table back to ns4xPlugin instance
memcpy((void*) &(plptr->fCallbacks), (void*)&callbacks, sizeof(callbacks));
#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;
// XXX This is suspicuous!
ns4xPluginInstance *inst = new ns4xPluginInstance(&fCallbacks, fLibrary);
if (inst == NULL)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(inst); // Stabilize
nsresult res = inst->QueryInterface(aIID, aResult);
NS_RELEASE(inst); // Destabilize and avoid leaks. Avoid calling delete <interface pointer>
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)
{
if (nsnull == fLibrary)
return NS_ERROR_FAILURE;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
nsresult
ns4xPlugin::Shutdown(void)
{
NPP_PLUGIN_LOG(PLUGIN_LOG_BASIC, ("NPP Shutdown to be called: this=%p\n",this));
if (nsnull != fShutdownEntry) {
#if defined(XP_MAC) || defined(XP_MACOSX)
CallNPP_ShutdownProc(fShutdownEntry);
::CloseResFile(fPluginRefNum);
#else
NS_TRY_SAFE_CALL_VOID(fShutdownEntry(), fLibrary, nsnull);
#endif
#if defined(XP_MACOSX)
// release the wrapped plugin function.
free(fShutdownEntry);
#endif
fShutdownEntry = nsnull;
}
PLUGIN_LOG(PLUGIN_LOG_NORMAL,("4xPlugin Shutdown done, this=%p",this));
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
nsresult
ns4xPlugin::GetMIMEDescription(const char* *resultingDesc)
{
const char* (*npGetMIMEDescription)() = (const char* (*)()) PR_FindSymbol(fLibrary, "NP_GetMIMEDescription");
*resultingDesc = npGetMIMEDescription ? npGetMIMEDescription() : "";
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("ns4xPlugin::GetMIMEDescription called: this=%p, result=%s\n",this, *resultingDesc));
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
nsresult
ns4xPlugin::GetValue(nsPluginVariable variable, void *value)
{
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("ns4xPlugin::GetValue called: this=%p, variable=%d\n",this,variable));
NPError (*npGetValue)(void*, nsPluginVariable, void*) =
(NPError (*)(void*, nsPluginVariable, void*)) PR_FindSymbol(fLibrary, "NP_GetValue");
if (npGetValue && NPERR_NO_ERROR == npGetValue(nsnull, variable, value)) {
return NS_OK;
}
else {
return NS_ERROR_FAILURE;
}
}
// Create a new NPP GET or POST url stream that may have a notify callback
NPError MakeNew4xStreamInternal (NPP npp,
const char *relativeURL,
const char *target,
eNPPStreamTypeInternal type, /* GET or POST */
PRBool bDoNotify = PR_FALSE,
void *notifyData = nsnull,
uint32 len = 0,
const char *buf = nsnull,
NPBool file = PR_FALSE)
{
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;
nsCOMPtr<nsIPluginManager> pm = do_GetService(kPluginManagerCID);
NS_ASSERTION(pm, "failed to get plugin manager");
if (!pm) return NPERR_GENERIC_ERROR;
nsIPluginStreamListener* listener = nsnull;
if(target == nsnull)
((ns4xPluginInstance*)inst)->NewNotifyStream(&listener, notifyData, bDoNotify, relativeURL);
switch (type) {
case eNPPStreamTypeInternal_Get:
{
if(NS_FAILED(pm->GetURL(inst, relativeURL, target, listener)))
return NPERR_GENERIC_ERROR;
break;
}
case eNPPStreamTypeInternal_Post:
{
if(NS_FAILED(pm->PostURL(inst, relativeURL, len, buf, file, target, listener)))
return NPERR_GENERIC_ERROR;
break;
}
default:
NS_ASSERTION(0, "how'd I get here");
}
return NPERR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////
//
// Static callbacks that get routed back through the new C++ API
//
NPError NP_EXPORT
_geturl(NPP npp, const char* relativeURL, const char* target)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPN_GetURL: npp=%p, target=%s, url=%s\n", (void *)npp, target, relativeURL));
return MakeNew4xStreamInternal (npp, relativeURL, target, eNPPStreamTypeInternal_Get);
}
////////////////////////////////////////////////////////////////////////
NPError NP_EXPORT
_geturlnotify(NPP npp, const char* relativeURL, const char* target, void* notifyData)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPN_GetURLNotify: npp=%p, target=%s, notify=%p, url=%s\n", (void*)npp, target, notifyData, relativeURL));
return MakeNew4xStreamInternal (npp, relativeURL, target, eNPPStreamTypeInternal_Get, PR_TRUE, notifyData);
}
////////////////////////////////////////////////////////////////////////
NPError NP_EXPORT
_posturlnotify(NPP npp, const char *relativeURL, const char *target,
uint32 len, const char *buf, NPBool file, void *notifyData)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPN_PostURLNotify: npp=%p, target=%s, len=%d, file=%d, notify=%p, url=%s, buf=%s\n",
(void*)npp, target, len, file, notifyData, relativeURL, buf));
return MakeNew4xStreamInternal (npp, relativeURL, target, eNPPStreamTypeInternal_Post,
PR_TRUE, notifyData, len, buf, file);
}
////////////////////////////////////////////////////////////////////////
NPError NP_EXPORT
_posturl(NPP npp, const char *relativeURL, const char *target,
uint32 len, const char *buf, NPBool file)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPN_PostURL: npp=%p, target=%s, file=%d, len=%d, url=%s, buf=%s\n",
(void*)npp, target, file, len, relativeURL, buf));
return MakeNew4xStreamInternal (npp, relativeURL, target, eNPPStreamTypeInternal_Post,
PR_FALSE, nsnull, len, buf, file);
}
////////////////////////////////////////////////////////////////////////
// A little helper class used to wrap up plugin manager streams (that is,
// streams from the plugin to the browser).
class ns4xStreamWrapper : nsISupports
{
public:
NS_DECL_ISUPPORTS
protected:
nsIOutputStream *fStream;
NPStream fNPStream;
public:
ns4xStreamWrapper(nsIOutputStream* stream);
~ns4xStreamWrapper();
void GetStream(nsIOutputStream* &result);
NPStream* GetNPStream(void) { return &fNPStream; };
};
NS_IMPL_ISUPPORTS1(ns4xStreamWrapper, nsISupports);
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
_newstream(NPP npp, NPMIMEType type, const char* window, NPStream* *result)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPN_NewStream: npp=%p, type=%s, window=%s\n", (void*)npp, (const char *)type, window));
NPError err = NPERR_INVALID_INSTANCE_ERROR;
if(npp && npp->ndata) {
nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata;
nsCOMPtr<nsIOutputStream> stream;
nsCOMPtr<nsIPluginInstancePeer> peer;
if (NS_SUCCEEDED(inst->GetPeer(getter_AddRefs(peer))) &&
peer &&
NS_SUCCEEDED(peer->NewStream((const char*) type, window, getter_AddRefs(stream))))
{
ns4xStreamWrapper* wrapper = new ns4xStreamWrapper(stream);
if (wrapper) {
(*result) = wrapper->GetNPStream();
err = NPERR_NO_ERROR;
} else {
err = NPERR_OUT_OF_MEMORY_ERROR;
}
} else {
err = NPERR_GENERIC_ERROR;
}
}
return err;
}
////////////////////////////////////////////////////////////////////////
int32 NP_EXPORT
_write(NPP npp, NPStream *pstream, int32 len, void *buffer)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPN_Write: npp=%p, url=%s, len=%d, buffer=%s\n", (void*)npp, pstream->url, len, (char*)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
_destroystream(NPP npp, NPStream *pstream, NPError reason)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPN_DestroyStream: npp=%p, url=%s, reason=%d\n", (void*)npp, pstream->url, (int)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;
pstream->ndata = nsnull;
return NPERR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////
void NP_EXPORT
_status(NPP npp, const char *message)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_Status: npp=%p, message=%s\n", (void*)npp, message));
if(!npp || !npp->ndata) {
NS_WARNING("_status: npp or npp->ndata == 0");
return;
}
nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata;
nsCOMPtr<nsIPluginInstancePeer> peer;
if (NS_SUCCEEDED(inst->GetPeer(getter_AddRefs(peer))) && peer) {
peer->ShowStatus(message);
}
}
////////////////////////////////////////////////////////////////////////
void NP_EXPORT
_memfree (void *ptr)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPN_MemFree: ptr=%p\n", ptr));
if(ptr)
gMalloc->Free(ptr);
}
////////////////////////////////////////////////////////////////////////
uint32 NP_EXPORT
_memflush(uint32 size)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPN_MemFlush: size=%d\n", size));
gMalloc->HeapMinimize(PR_TRUE);
return 0;
}
////////////////////////////////////////////////////////////////////////
void NP_EXPORT
_reloadplugins(NPBool reloadPages)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_ReloadPlugins: reloadPages=%d\n", reloadPages));
NS_ASSERTION(gServiceMgr != NULL, "null service manager");
if(gServiceMgr == nsnull)
return;
nsIPluginManager * pm;
gServiceMgr->GetService(kPluginManagerCID, kIPluginManagerIID, (nsISupports**)&pm);
pm->ReloadPlugins(reloadPages);
NS_RELEASE(pm);
}
////////////////////////////////////////////////////////////////////////
void NP_EXPORT
_invalidaterect(NPP npp, NPRect *invalidRect)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPN_InvalidateRect: npp=%p, top=%d, left=%d, bottom=%d, right=%d\n",
(void *)npp, invalidRect->top, invalidRect->left, invalidRect->bottom, invalidRect->right));
if(!npp || !npp->ndata) {
NS_WARNING("_invalidaterect: npp or npp->ndata == 0");
return;
}
nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata;
nsCOMPtr<nsIPluginInstancePeer> peer;
if (NS_SUCCEEDED(inst->GetPeer(getter_AddRefs(peer))) && peer) {
nsCOMPtr<nsIWindowlessPluginInstancePeer> wpeer(do_QueryInterface(peer));
if (wpeer) {
// XXX nsRect & NPRect are structurally equivalent
wpeer->InvalidateRect((nsPluginRect *)invalidRect);
}
}
}
////////////////////////////////////////////////////////////////////////
void NP_EXPORT
_invalidateregion(NPP npp, NPRegion invalidRegion)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("NPN_InvalidateRegion: npp=%p, region=%p\n", (void*)npp, (void*)invalidRegion));
if(!npp || !npp->ndata) {
NS_WARNING("_invalidateregion: npp or npp->ndata == 0");
return;
}
nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata;
nsCOMPtr<nsIPluginInstancePeer> peer;
if (NS_SUCCEEDED(inst->GetPeer(getter_AddRefs(peer))) && peer) {
nsCOMPtr<nsIWindowlessPluginInstancePeer> wpeer(do_QueryInterface(peer));
if (wpeer) {
// XXX nsRegion & NPRegion are typedef'd to the same thing
wpeer->InvalidateRegion((nsPluginRegion)invalidRegion);
}
}
}
////////////////////////////////////////////////////////////////////////
void NP_EXPORT
_forceredraw(NPP npp)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_ForceDraw: npp=%p\n", (void*)npp));
if(!npp || !npp->ndata) {
NS_WARNING("_forceredraw: npp or npp->ndata == 0");
return;
}
nsIPluginInstance *inst = (nsIPluginInstance *) npp->ndata;
nsCOMPtr<nsIPluginInstancePeer> peer;
if (NS_SUCCEEDED(inst->GetPeer(getter_AddRefs(peer))) && peer) {
nsCOMPtr<nsIWindowlessPluginInstancePeer> wpeer(do_QueryInterface(peer));
if (wpeer) {
wpeer->ForceRedraw();
}
}
}
////////////////////////////////////////////////////////////////////////
NPError NP_EXPORT
_getvalue(NPP npp, NPNVariable variable, void *result)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetValue: npp=%p, var=%d\n", (void*)npp, (int)variable));
nsresult res;
switch(variable) {
#if defined(XP_UNIX) && !defined(XP_MACOSX)
case NPNVxDisplay : {
#if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_GTK2)
// adobe nppdf calls XtGetApplicationNameAndClass(display, &instance, &class)
// we have to init Xt toolkit before get XtDisplay
// just call gtk_xtbin_new(w,0) once
static GtkWidget *gtkXtBinHolder = 0;
if (!gtkXtBinHolder) {
gtkXtBinHolder = gtk_xtbin_new(GDK_ROOT_PARENT(),0);
// it crashes on destroy, let it leak
// gtk_widget_destroy(gtkXtBinHolder);
}
(*(Display **)result) = GTK_XTBIN(gtkXtBinHolder)->xtdisplay;
return NPERR_NO_ERROR;
#endif
return NPERR_GENERIC_ERROR;
}
case NPNVxtAppContext:
return NPERR_GENERIC_ERROR;
#endif
#ifdef XP_PC
case NPNVnetscapeWindow: {
if (!npp || !npp->ndata)
return NPERR_INVALID_INSTANCE_ERROR;
ns4xPluginInstance *inst = (ns4xPluginInstance *) npp->ndata;
nsCOMPtr<nsIPluginInstancePeer> peer;
if (NS_SUCCEEDED(inst->GetPeer(getter_AddRefs(peer))) &&
peer &&
NS_SUCCEEDED(peer->GetValue(nsPluginInstancePeerVariable_NetscapeWindow, result)))
{
return NPERR_NO_ERROR;
}
return NPERR_GENERIC_ERROR;
}
#endif
case NPNVjavascriptEnabledBool: {
*(NPBool*)result = PR_FALSE;
nsCOMPtr<nsIPref> prefs(do_GetService(kPrefServiceCID));
if(prefs) {
PRBool js = PR_FALSE;;
res = prefs->GetBoolPref("javascript.enabled", &js);
if(NS_SUCCEEDED(res))
*(NPBool*)result = js;
}
return NPERR_NO_ERROR;
}
case NPNVasdEnabledBool:
*(NPBool*)result = FALSE;
return NPERR_NO_ERROR;
case NPNVisOfflineBool:
*(NPBool*)result = FALSE;
return NPERR_NO_ERROR;
case NPNVserviceManager: {
nsIServiceManager * sm;
res = NS_GetServiceManager(&sm);
if (NS_SUCCEEDED(res)) {
*(nsIServiceManager**)result = sm;
return NPERR_NO_ERROR;
} else
return NPERR_GENERIC_ERROR;
}
case NPNVDOMElement: {
ns4xPluginInstance *inst = (ns4xPluginInstance *) npp->ndata;
NS_ENSURE_TRUE(inst, NPERR_GENERIC_ERROR);
nsCOMPtr<nsIPluginInstancePeer> pip;
inst->GetPeer(getter_AddRefs(pip));
nsCOMPtr<nsIPluginTagInfo2> pti2 (do_QueryInterface(pip));
if (pti2) {
nsCOMPtr<nsIDOMElement> e;
pti2->GetDOMElement(getter_AddRefs(e));
if (e) {
NS_ADDREF(*(nsIDOMElement**)result = e.get());
return NPERR_NO_ERROR;
}
}
return NPERR_GENERIC_ERROR;
}
case NPNVDOMWindow: {
ns4xPluginInstance *inst = (ns4xPluginInstance *) npp->ndata;
NS_ENSURE_TRUE(inst, NPERR_GENERIC_ERROR);
nsCOMPtr<nsIPluginInstancePeer> pip;
inst->GetPeer(getter_AddRefs(pip));
nsCOMPtr<nsPIPluginInstancePeer> pp (do_QueryInterface(pip));
if (pp) {
nsCOMPtr<nsIPluginInstanceOwner> owner;
pp->GetOwner(getter_AddRefs(owner));
if (owner) {
nsCOMPtr<nsIDocument> doc;
owner->GetDocument(getter_AddRefs(doc));
if (doc) {
nsCOMPtr<nsIScriptGlobalObject> globalScript;
doc->GetScriptGlobalObject(getter_AddRefs(globalScript));
nsCOMPtr<nsIDOMWindow> domWindow (do_QueryInterface(globalScript));
if (domWindow) {
NS_ADDREF(*(nsIDOMWindow**)result = domWindow.get());
return NPERR_NO_ERROR;
}
}
}
}
return NPERR_GENERIC_ERROR;
}
default : return NPERR_GENERIC_ERROR;
}
}
////////////////////////////////////////////////////////////////////////
NPError NP_EXPORT
_setvalue(NPP npp, NPPVariable variable, void *result)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_SetValue: npp=%p, var=%d\n", (void*)npp, (int)variable));
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) {
// we should keep backward compatibility with 4x where the
// actual pointer value is checked rather than its content
// wnen passing booleans
case NPPVpluginWindowBool: {
NPBool bWindowless = (result == nsnull);
return inst->SetWindowless(bWindowless);
}
case NPPVpluginTransparentBool: {
NPBool bTransparent = (result != nsnull);
return inst->SetTransparent(bTransparent);
}
case NPPVjavascriptPushCallerBool:
{
nsresult rv;
nsCOMPtr<nsIJSContextStack> contextStack = do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
if (NS_SUCCEEDED(rv)) {
NPBool bPushCaller = (result != nsnull);
if (bPushCaller) {
nsCOMPtr<nsIPluginInstancePeer> peer;
if (NS_SUCCEEDED(inst->GetPeer(getter_AddRefs(peer))) && peer) {
nsCOMPtr<nsIPluginInstancePeer2> peer2 = do_QueryInterface(peer, &rv);
if (NS_SUCCEEDED(rv) && peer2) {
JSContext *cx;
rv = peer2->GetJSContext(&cx);
if (NS_SUCCEEDED(rv))
rv = contextStack->Push(cx);
}
}
} else {
rv = contextStack->Pop(nsnull);
}
}
return NS_SUCCEEDED(rv) ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
}
break;
case NPPVpluginKeepLibraryInMemory: {
NPBool bCached = (result != nsnull);
return inst->SetCached(bCached);
}
default:
return NPERR_NO_ERROR;
}
}
////////////////////////////////////////////////////////////////////////
NPError NP_EXPORT
_requestread(NPStream *pstream, NPByteRange *rangeList)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_RequestRead: stream=%p\n", (void*)pstream));
#if PLUGIN_LOGGING
for(NPByteRange * range = rangeList; range != nsnull; range = range->next)
PR_LOG(nsPluginLogging::gNPNLog,PLUGIN_LOG_NOISY,
("%i-%i", range->offset, range->offset + range->length - 1));
PR_LOG(nsPluginLogging::gNPNLog,PLUGIN_LOG_NOISY, ("\n\n"));
PR_LogFlush();
#endif
if(!pstream || !rangeList || !pstream->ndata)
return NPERR_INVALID_PARAM;
nsresult res = NS_OK;
ns4xPluginStreamListener * streamlistener = (ns4xPluginStreamListener *)pstream->ndata;
if(NS_FAILED(res))
return NPERR_GENERIC_ERROR;
nsPluginStreamType streamtype = nsPluginStreamType_Normal;
streamlistener->GetStreamType(&streamtype);
if(streamtype != nsPluginStreamType_Seek)
return NPERR_STREAM_NOT_SEEKABLE;
if(streamlistener->mStreamInfo)
streamlistener->mStreamInfo->RequestRead((nsByteRange *)rangeList);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
//
// 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
_getJavaEnv(void)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaEnv\n"));
return NULL;
}
////////////////////////////////////////////////////////////////////////
const char * NP_EXPORT
_useragent(NPP npp)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_UserAgent: npp=%p\n", (void*)npp));
NS_ASSERTION(gServiceMgr != NULL, "null service manager");
if (gServiceMgr == NULL)
return NULL;
char *retstr;
nsIPluginManager * pm;
gServiceMgr->GetService(kPluginManagerCID, kIPluginManagerIID, (nsISupports**)&pm);
pm->UserAgent((const char **)&retstr);
NS_RELEASE(pm);
return retstr;
}
////////////////////////////////////////////////////////////////////////
void * NP_EXPORT
_memalloc (uint32 size)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NOISY, ("NPN_MemAlloc: size=%d\n", size));
return gMalloc->Alloc(size);
}
////////////////////////////////////////////////////////////////////////
java_lang_Class* NP_EXPORT
_getJavaClass(void* handle)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaClass\n"));
return NULL;
}
////////////////////////////////////////////////////////////////////////
jref NP_EXPORT
_getJavaPeer(NPP npp)
{
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_GetJavaPeer: npp=%p\n", (void*)npp));
return NULL;
}