michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * vim: sw=2 ts=8 et : michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "mozilla/PluginPRLibrary.h" michael@0: #include "nsNPAPIPluginInstance.h" michael@0: michael@0: // Some plugins on Windows, notably Quake Live, implement NP_Initialize using michael@0: // cdecl instead of the documented stdcall. In order to work around this, michael@0: // we force the caller to use a frame pointer. michael@0: #if defined(XP_WIN) && defined(_M_IX86) michael@0: #include michael@0: michael@0: // gNotOptimized exists so that the compiler will not optimize the alloca michael@0: // below. michael@0: static int gNotOptimized; michael@0: #define CALLING_CONVENTION_HACK void* foo = _alloca(gNotOptimized); michael@0: #else michael@0: #define CALLING_CONVENTION_HACK michael@0: #endif michael@0: michael@0: #ifdef MOZ_WIDGET_ANDROID michael@0: #include "AndroidBridge.h" michael@0: #include "android_npapi.h" michael@0: #include michael@0: #undef ALOG michael@0: #define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoJavaEnv", ## args) michael@0: #endif michael@0: michael@0: using namespace mozilla::layers; michael@0: michael@0: namespace mozilla { michael@0: #ifdef MOZ_WIDGET_ANDROID michael@0: nsresult michael@0: PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs, michael@0: NPPluginFuncs* pFuncs, NPError* error) michael@0: { michael@0: JNIEnv* env = GetJNIForThread(); michael@0: michael@0: mozilla::AutoLocalJNIFrame jniFrame(env); michael@0: michael@0: if (mNP_Initialize) { michael@0: *error = mNP_Initialize(bFuncs, pFuncs, env); michael@0: } else { michael@0: NP_InitializeFunc pfNP_Initialize = (NP_InitializeFunc) michael@0: PR_FindFunctionSymbol(mLibrary, "NP_Initialize"); michael@0: if (!pfNP_Initialize) michael@0: return NS_ERROR_FAILURE; michael@0: *error = pfNP_Initialize(bFuncs, pFuncs, env); michael@0: } michael@0: michael@0: // Save pointers to functions that get called through PluginLibrary itself. michael@0: mNPP_New = pFuncs->newp; michael@0: mNPP_ClearSiteData = pFuncs->clearsitedata; michael@0: mNPP_GetSitesWithData = pFuncs->getsiteswithdata; michael@0: return NS_OK; michael@0: } michael@0: #elif defined(MOZ_WIDGET_GONK) michael@0: nsresult michael@0: PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) michael@0: { michael@0: return NS_OK; michael@0: } michael@0: #elif defined(XP_UNIX) && !defined(XP_MACOSX) michael@0: nsresult michael@0: PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs, michael@0: NPPluginFuncs* pFuncs, NPError* error) michael@0: { michael@0: if (mNP_Initialize) { michael@0: *error = mNP_Initialize(bFuncs, pFuncs); michael@0: } else { michael@0: NP_InitializeFunc pfNP_Initialize = (NP_InitializeFunc) michael@0: PR_FindFunctionSymbol(mLibrary, "NP_Initialize"); michael@0: if (!pfNP_Initialize) michael@0: return NS_ERROR_FAILURE; michael@0: *error = pfNP_Initialize(bFuncs, pFuncs); michael@0: } michael@0: michael@0: michael@0: // Save pointers to functions that get called through PluginLibrary itself. michael@0: mNPP_New = pFuncs->newp; michael@0: mNPP_ClearSiteData = pFuncs->clearsitedata; michael@0: mNPP_GetSitesWithData = pFuncs->getsiteswithdata; michael@0: return NS_OK; michael@0: } michael@0: #else michael@0: nsresult michael@0: PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error) michael@0: { michael@0: CALLING_CONVENTION_HACK michael@0: michael@0: if (mNP_Initialize) { michael@0: *error = mNP_Initialize(bFuncs); michael@0: } else { michael@0: NP_InitializeFunc pfNP_Initialize = (NP_InitializeFunc) michael@0: PR_FindFunctionSymbol(mLibrary, "NP_Initialize"); michael@0: if (!pfNP_Initialize) michael@0: return NS_ERROR_FAILURE; michael@0: *error = pfNP_Initialize(bFuncs); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: #endif michael@0: michael@0: nsresult michael@0: PluginPRLibrary::NP_Shutdown(NPError* error) michael@0: { michael@0: CALLING_CONVENTION_HACK michael@0: michael@0: if (mNP_Shutdown) { michael@0: *error = mNP_Shutdown(); michael@0: } else { michael@0: NP_ShutdownFunc pfNP_Shutdown = (NP_ShutdownFunc) michael@0: PR_FindFunctionSymbol(mLibrary, "NP_Shutdown"); michael@0: if (!pfNP_Shutdown) michael@0: return NS_ERROR_FAILURE; michael@0: *error = pfNP_Shutdown(); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: PluginPRLibrary::NP_GetMIMEDescription(const char** mimeDesc) michael@0: { michael@0: CALLING_CONVENTION_HACK michael@0: michael@0: if (mNP_GetMIMEDescription) { michael@0: *mimeDesc = mNP_GetMIMEDescription(); michael@0: } michael@0: else { michael@0: NP_GetMIMEDescriptionFunc pfNP_GetMIMEDescription = michael@0: (NP_GetMIMEDescriptionFunc) michael@0: PR_FindFunctionSymbol(mLibrary, "NP_GetMIMEDescription"); michael@0: if (!pfNP_GetMIMEDescription) { michael@0: *mimeDesc = ""; michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: *mimeDesc = pfNP_GetMIMEDescription(); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: PluginPRLibrary::NP_GetValue(void *future, NPPVariable aVariable, michael@0: void *aValue, NPError* error) michael@0: { michael@0: #if defined(XP_UNIX) && !defined(XP_MACOSX) michael@0: if (mNP_GetValue) { michael@0: *error = mNP_GetValue(future, aVariable, aValue); michael@0: } else { michael@0: NP_GetValueFunc pfNP_GetValue = (NP_GetValueFunc)PR_FindFunctionSymbol(mLibrary, "NP_GetValue"); michael@0: if (!pfNP_GetValue) michael@0: return NS_ERROR_FAILURE; michael@0: *error = pfNP_GetValue(future, aVariable, aValue); michael@0: } michael@0: return NS_OK; michael@0: #else michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: #endif michael@0: } michael@0: michael@0: #if defined(XP_WIN) || defined(XP_MACOSX) michael@0: nsresult michael@0: PluginPRLibrary::NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) michael@0: { michael@0: CALLING_CONVENTION_HACK michael@0: michael@0: if (mNP_GetEntryPoints) { michael@0: *error = mNP_GetEntryPoints(pFuncs); michael@0: } else { michael@0: NP_GetEntryPointsFunc pfNP_GetEntryPoints = (NP_GetEntryPointsFunc) michael@0: PR_FindFunctionSymbol(mLibrary, "NP_GetEntryPoints"); michael@0: if (!pfNP_GetEntryPoints) michael@0: return NS_ERROR_FAILURE; michael@0: *error = pfNP_GetEntryPoints(pFuncs); michael@0: } michael@0: michael@0: // Save pointers to functions that get called through PluginLibrary itself. michael@0: mNPP_New = pFuncs->newp; michael@0: mNPP_ClearSiteData = pFuncs->clearsitedata; michael@0: mNPP_GetSitesWithData = pFuncs->getsiteswithdata; michael@0: return NS_OK; michael@0: } michael@0: #endif michael@0: michael@0: nsresult michael@0: PluginPRLibrary::NPP_New(NPMIMEType pluginType, NPP instance, michael@0: uint16_t mode, int16_t argc, char* argn[], michael@0: char* argv[], NPSavedData* saved, michael@0: NPError* error) michael@0: { michael@0: if (!mNPP_New) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: MAIN_THREAD_JNI_REF_GUARD; michael@0: *error = mNPP_New(pluginType, instance, mode, argc, argn, argv, saved); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: PluginPRLibrary::NPP_ClearSiteData(const char* site, uint64_t flags, michael@0: uint64_t maxAge) michael@0: { michael@0: if (!mNPP_ClearSiteData) { michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: MAIN_THREAD_JNI_REF_GUARD; michael@0: NPError result = mNPP_ClearSiteData(site, flags, maxAge); michael@0: michael@0: switch (result) { michael@0: case NPERR_NO_ERROR: michael@0: return NS_OK; michael@0: case NPERR_TIME_RANGE_NOT_SUPPORTED: michael@0: return NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED; michael@0: case NPERR_MALFORMED_SITE: michael@0: return NS_ERROR_INVALID_ARG; michael@0: default: michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: } michael@0: michael@0: nsresult michael@0: PluginPRLibrary::NPP_GetSitesWithData(InfallibleTArray& result) michael@0: { michael@0: if (!mNPP_GetSitesWithData) { michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: result.Clear(); michael@0: michael@0: MAIN_THREAD_JNI_REF_GUARD; michael@0: char** sites = mNPP_GetSitesWithData(); michael@0: if (!sites) { michael@0: return NS_OK; michael@0: } michael@0: michael@0: char** iterator = sites; michael@0: while (*iterator) { michael@0: result.AppendElement(*iterator); michael@0: NS_Free(*iterator); michael@0: ++iterator; michael@0: } michael@0: NS_Free(sites); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: PluginPRLibrary::AsyncSetWindow(NPP instance, NPWindow* window) michael@0: { michael@0: nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata; michael@0: NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER); michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: nsresult michael@0: PluginPRLibrary::GetImageContainer(NPP instance, ImageContainer** aContainer) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: #if defined(XP_MACOSX) michael@0: nsresult michael@0: PluginPRLibrary::IsRemoteDrawingCoreAnimation(NPP instance, bool *aDrawing) michael@0: { michael@0: nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata; michael@0: NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER); michael@0: *aDrawing = false; michael@0: return NS_OK; michael@0: } michael@0: nsresult michael@0: PluginPRLibrary::ContentsScaleFactorChanged(NPP instance, double aContentsScaleFactor) michael@0: { michael@0: nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata; michael@0: NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER); michael@0: return NS_OK; michael@0: } michael@0: #endif michael@0: michael@0: nsresult michael@0: PluginPRLibrary::GetImageSize(NPP instance, nsIntSize* aSize) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: nsresult michael@0: PluginPRLibrary::SetBackgroundUnknown(NPP instance) michael@0: { michael@0: nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata; michael@0: NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER); michael@0: NS_ERROR("Unexpected use of async APIs for in-process plugin."); michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: nsresult michael@0: PluginPRLibrary::BeginUpdateBackground(NPP instance, michael@0: const nsIntRect&, gfxContext** aCtx) michael@0: { michael@0: nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata; michael@0: NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER); michael@0: NS_ERROR("Unexpected use of async APIs for in-process plugin."); michael@0: *aCtx = nullptr; michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: PluginPRLibrary::EndUpdateBackground(NPP instance, michael@0: gfxContext*, const nsIntRect&) michael@0: { michael@0: NS_RUNTIMEABORT("This should never be called"); michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: } // namespace mozilla