blob: f7b15abb86c0dd784e9a7bac6f4f7371702d53f5 [file] [log] [blame]
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/default_plugin/plugin_main.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "chrome/default_plugin/plugin_impl.h"
#include "webkit/glue/webkit_glue.h"
namespace default_plugin {
#if defined(OS_WIN)
//
// Forward declare the linker-provided pseudo variable for the
// current module handle.
//
extern "C" IMAGE_DOS_HEADER __ImageBase;
// get the handle to the currently executing module
inline HMODULE GetCurrentModuleHandle() {
return reinterpret_cast<HINSTANCE>(&__ImageBase);
}
#endif
// Initialized in NP_Initialize.
NPNetscapeFuncs* g_browser = NULL;
NPError API_CALL NP_GetEntryPoints(NPPluginFuncs* funcs) {
// Be explicit about the namespace, because all internal plugins have
// functions with these names and some might accidentally put them into the
// global namespace. In that case, the linker might prefer the global one.
funcs->version = 11;
funcs->size = sizeof(*funcs);
funcs->newp = default_plugin::NPP_New;
funcs->destroy = default_plugin::NPP_Destroy;
funcs->setwindow = default_plugin::NPP_SetWindow;
funcs->newstream = default_plugin::NPP_NewStream;
funcs->destroystream = default_plugin::NPP_DestroyStream;
funcs->writeready = default_plugin::NPP_WriteReady;
funcs->write = default_plugin::NPP_Write;
funcs->asfile = NULL;
funcs->print = NULL;
funcs->event = default_plugin::NPP_HandleEvent;
funcs->urlnotify = default_plugin::NPP_URLNotify;
#if defined(OS_POSIX) && !defined(OS_MACOSX)
funcs->getvalue = default_plugin::NPP_GetValue;
#else
funcs->getvalue = NULL;
#endif
funcs->setvalue = NULL;
return NPERR_NO_ERROR;
}
NPError API_CALL NP_Initialize(NPNetscapeFuncs* funcs) {
g_browser = funcs;
return 0;
}
#if defined(OS_POSIX) && !defined(OS_MACOSX)
NPError API_CALL NP_Initialize(NPNetscapeFuncs* funcs, NPPluginFuncs* p_funcs) {
NPError err = NP_Initialize(funcs);
if (err != NPERR_NO_ERROR)
return err;
return NP_GetEntryPoints(p_funcs);
}
#endif
NPError API_CALL NP_Shutdown(void) {
g_browser = NULL;
return NPERR_NO_ERROR;
}
namespace {
// This function is only invoked when the default plugin is invoked
// with a special mime type application/chromium-test-default-plugin
void SignalTestResult(NPP instance) {
NPObject *window_obj = NULL;
g_browser->getvalue(instance, NPNVWindowNPObject, &window_obj);
if (!window_obj) {
NOTREACHED();
return;
}
std::string script = "javascript:onSuccess()";
NPString script_string;
script_string.UTF8Characters = script.c_str();
script_string.UTF8Length =
static_cast<unsigned int>(script.length());
NPVariant result_var;
g_browser->evaluate(instance, window_obj,
&script_string, &result_var);
g_browser->releaseobject(window_obj);
}
} // namespace CHROMIUM_DefaultPluginTest
bool NegotiateModels(NPP instance) {
#if defined(OS_MACOSX)
NPError err;
// Set drawing model to core graphics
NPBool supportsCoreGraphics = false;
err = g_browser->getvalue(instance,
NPNVsupportsCoreGraphicsBool,
&supportsCoreGraphics);
if (err != NPERR_NO_ERROR || !supportsCoreGraphics) {
NOTREACHED();
return false;
}
err = g_browser->setvalue(instance,
NPPVpluginDrawingModel,
(void*)NPDrawingModelCoreGraphics);
if (err != NPERR_NO_ERROR) {
NOTREACHED();
return false;
}
// Set event model to cocoa
NPBool supportsCocoaEvents = false;
err = g_browser->getvalue(instance,
NPNVsupportsCocoaBool,
&supportsCocoaEvents);
if (err != NPERR_NO_ERROR || !supportsCocoaEvents) {
NOTREACHED();
return false;
}
err = g_browser->setvalue(instance,
NPPVpluginEventModel,
(void*)NPEventModelCocoa);
if (err != NPERR_NO_ERROR) {
NOTREACHED();
return false;
}
#elif defined(OS_POSIX)
NPError err;
// Check that chrome still supports xembed.
NPBool supportsXEmbed = false;
err = g_browser->getvalue(instance,
NPNVSupportsXEmbedBool,
&supportsXEmbed);
if (err != NPERR_NO_ERROR || !supportsXEmbed) {
NOTREACHED();
return false;
}
// Check that the toolkit is still gtk2.
NPNToolkitType toolkit;
err = g_browser->getvalue(instance,
NPNVToolkit,
&toolkit);
if (err != NPERR_NO_ERROR || toolkit != NPNVGtk2) {
NOTREACHED();
return false;
}
#endif
return true;
}
NPError NPP_New(NPMIMEType plugin_type, NPP instance, uint16_t mode,
int16_t argc, char* argn[], char* argv[], NPSavedData* saved) {
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
if (!NegotiateModels(instance))
return NPERR_INCOMPATIBLE_VERSION_ERROR;
PluginInstallerImpl* plugin_impl = new PluginInstallerImpl(mode);
plugin_impl->Initialize(
#if defined(OS_WIN)
GetCurrentModuleHandle(),
#else
NULL,
#endif
instance, plugin_type, argc,
argn, argv);
instance->pdata = reinterpret_cast<void*>(plugin_impl);
if (!base::strcasecmp(plugin_type,
"application/chromium-test-default-plugin")) {
SignalTestResult(instance);
}
return NPERR_NO_ERROR;
}
NPError NPP_Destroy(NPP instance, NPSavedData** save) {
PluginInstallerImpl* plugin_impl =
reinterpret_cast<PluginInstallerImpl*>(instance->pdata);
if (plugin_impl) {
plugin_impl->Shutdown();
delete plugin_impl;
}
return NPERR_NO_ERROR;
}
NPError NPP_SetWindow(NPP instance, NPWindow* window_info) {
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
if (window_info == NULL) {
NOTREACHED();
return NPERR_GENERIC_ERROR;
}
PluginInstallerImpl* plugin_impl =
reinterpret_cast<PluginInstallerImpl*>(instance->pdata);
if (plugin_impl == NULL) {
NOTREACHED();
return NPERR_GENERIC_ERROR;
}
if (!plugin_impl->NPP_SetWindow(window_info)) {
delete plugin_impl;
return NPERR_GENERIC_ERROR;
}
return NPERR_NO_ERROR;
}
NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
NPBool seekable, uint16_t* stype) {
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
PluginInstallerImpl* plugin_impl =
reinterpret_cast<PluginInstallerImpl*>(instance->pdata);
if (!plugin_impl) {
NOTREACHED();
return NPERR_INVALID_INSTANCE_ERROR;
}
plugin_impl->NewStream(stream);
return NPERR_NO_ERROR;
}
NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason) {
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
PluginInstallerImpl* plugin_impl =
reinterpret_cast<PluginInstallerImpl*>(instance->pdata);
if (!plugin_impl) {
NOTREACHED();
return NPERR_INVALID_INSTANCE_ERROR;
}
plugin_impl->DestroyStream(stream, reason);
return NPERR_NO_ERROR;
}
int32_t NPP_WriteReady(NPP instance, NPStream* stream) {
if (instance == NULL)
return 0;
PluginInstallerImpl* plugin_impl =
reinterpret_cast<PluginInstallerImpl*>(instance->pdata);
if (!plugin_impl) {
NOTREACHED();
return 0;
}
if (plugin_impl->WriteReady(stream))
return 0x7FFFFFFF;
return 0;
}
int32_t NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len,
void* buffer) {
if (instance == NULL)
return 0;
PluginInstallerImpl* plugin_impl =
reinterpret_cast<PluginInstallerImpl*>(instance->pdata);
if (!plugin_impl) {
NOTREACHED();
return 0;
}
return plugin_impl->Write(stream, offset, len, buffer);
}
void NPP_URLNotify(NPP instance, const char* url, NPReason reason,
void* notifyData) {
if (instance != NULL) {
PluginInstallerImpl* plugin_impl =
reinterpret_cast<PluginInstallerImpl*>(instance->pdata);
if (!plugin_impl) {
NOTREACHED();
return;
}
plugin_impl->URLNotify(url, reason);
}
}
#if defined(OS_POSIX) && !defined(OS_MACOSX)
NPError NPP_GetValue(NPP instance, NPPVariable variable, void* value) {
switch (variable) {
case NPPVpluginNeedsXEmbed:
*static_cast<NPBool*>(value) = true;
return NPERR_NO_ERROR;
default:
return NPERR_INVALID_PARAM;
}
}
#endif
int16_t NPP_HandleEvent(NPP instance, void* event) {
if (instance == NULL)
return 0;
PluginInstallerImpl* plugin_impl =
reinterpret_cast<PluginInstallerImpl*>(instance->pdata);
return plugin_impl->NPP_HandleEvent(event);
}
} // default_plugin