| // 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 |