diff options
Diffstat (limited to 'Source/WebKit2/WebProcess/Plugins')
22 files changed, 291 insertions, 69 deletions
diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp index edd2b44..fc73519 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp @@ -27,24 +27,25 @@ #include "JSNPMethod.h" #include "JSNPObject.h" -#include "NotImplemented.h" #include <JavaScriptCore/Error.h> #include <JavaScriptCore/FunctionPrototype.h> #include <JavaScriptCore/JSGlobalObject.h> #include <WebCore/JSHTMLElement.h> #include <WebCore/JSPluginElementFunctions.h> +#include <WebCore/NotImplemented.h> using namespace JSC; using namespace WebCore; namespace WebKit { -const ClassInfo JSNPMethod::s_info = { "NPMethod", &InternalFunction::info, 0, 0 }; +const ClassInfo JSNPMethod::s_info = { "NPMethod", &InternalFunction::s_info, 0, 0 }; JSNPMethod::JSNPMethod(ExecState* exec, JSGlobalObject* globalObject, const Identifier& name, NPIdentifier npIdentifier) : InternalFunction(&exec->globalData(), globalObject, createStructure(globalObject->functionPrototype()), name) , m_npIdentifier(npIdentifier) { + ASSERT(inherits(&s_info)); } static EncodedJSValue JSC_HOST_CALL callMethod(ExecState* exec) diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.h b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.h index 9a8578c..a913a99 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.h @@ -44,11 +44,10 @@ public: private: static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) { - return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount); + return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info); } virtual JSC::CallType getCallData(JSC::CallData&); - virtual const JSC::ClassInfo* classInfo() const { return &s_info; } NPIdentifier m_npIdentifier; }; diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp index f6939cb..2724f0d 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp @@ -47,13 +47,15 @@ static NPIdentifier npIdentifierFromIdentifier(const Identifier& identifier) return static_cast<NPIdentifier>(IdentifierRep::get(identifier.ustring().utf8().data())); } -const ClassInfo JSNPObject::s_info = { "NPObject", 0, 0, 0 }; +const ClassInfo JSNPObject::s_info = { "NPObject", &JSObjectWithGlobalObject::s_info, 0, 0 }; JSNPObject::JSNPObject(JSGlobalObject* globalObject, NPRuntimeObjectMap* objectMap, NPObject* npObject) : JSObjectWithGlobalObject(globalObject, createStructure(globalObject->objectPrototype())) , m_objectMap(objectMap) , m_npObject(npObject) { + ASSERT(inherits(&s_info)); + // We should never have an NPJSObject inside a JSNPObject. ASSERT(!NPJSObject::isNPJSObject(m_npObject)); diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h index af1369a..adaffa7 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h @@ -53,11 +53,11 @@ public: NPObject* npObject() const { return m_npObject; } private: - static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSObject::StructureFlags; + static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | JSObject::StructureFlags; static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) { - return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount); + return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info); } virtual JSC::CallType getCallData(JSC::CallData&); @@ -73,8 +73,6 @@ private: static JSC::JSValue methodGetter(JSC::ExecState*, JSC::JSValue, const JSC::Identifier&); static JSC::JSObject* throwInvalidAccessError(JSC::ExecState*); - virtual const JSC::ClassInfo* classInfo() const { return &s_info; } - NPRuntimeObjectMap* m_objectMap; NPObject* m_npObject; }; diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp index 345bd54..4c687f4 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp @@ -29,12 +29,12 @@ #include "JSNPObject.h" #include "NPRuntimeObjectMap.h" #include "NPRuntimeUtilities.h" -#include "NotImplemented.h" #include "PluginView.h" #include <JavaScriptCore/JSLock.h> #include <JavaScriptCore/JSObject.h> #include <WebCore/Frame.h> #include <WebCore/IdentifierRep.h> +#include <WebCore/NotImplemented.h> #include <wtf/text/WTFString.h> using namespace JSC; @@ -42,19 +42,20 @@ using namespace WebCore; namespace WebKit { -NPJSObject* NPJSObject::create(NPRuntimeObjectMap* objectMap, JSObject* jsObject) +NPJSObject* NPJSObject::create(JSGlobalData& globalData, NPRuntimeObjectMap* objectMap, JSObject* jsObject) { // We should never have a JSNPObject inside an NPJSObject. ASSERT(!jsObject->inherits(&JSNPObject::s_info)); NPJSObject* npJSObject = toNPJSObject(createNPObject(0, npClass())); - npJSObject->initialize(objectMap, jsObject); + npJSObject->initialize(globalData, objectMap, jsObject); return npJSObject; } NPJSObject::NPJSObject() : m_objectMap(0) + , m_jsObject(Global<JSObject>::EmptyValue) { } @@ -68,13 +69,13 @@ bool NPJSObject::isNPJSObject(NPObject* npObject) return npObject->_class == npClass(); } -void NPJSObject::initialize(NPRuntimeObjectMap* objectMap, JSObject* jsObject) +void NPJSObject::initialize(JSGlobalData& globalData, NPRuntimeObjectMap* objectMap, JSObject* jsObject) { ASSERT(!m_objectMap); ASSERT(!m_jsObject); m_objectMap = objectMap; - m_jsObject = jsObject; + m_jsObject.set(globalData, jsObject); } static Identifier identifierFromIdentifierRep(ExecState* exec, IdentifierRep* identifierRep) @@ -132,7 +133,7 @@ bool NPJSObject::invokeDefault(const NPVariant* arguments, uint32_t argumentCoun JSLock lock(SilenceAssertionsOnly); - JSValue function = m_jsObject; + JSValue function = m_jsObject.get(); return invoke(exec, m_objectMap->globalObject(), function, arguments, argumentCount, result); } @@ -259,7 +260,7 @@ bool NPJSObject::construct(const NPVariant* arguments, uint32_t argumentCount, N JSLock lock(SilenceAssertionsOnly); ConstructData constructData; - ConstructType constructType = getConstructData(m_jsObject, constructData); + ConstructType constructType = getConstructData(m_jsObject.get(), constructData); if (constructType == ConstructTypeNone) return false; @@ -269,7 +270,7 @@ bool NPJSObject::construct(const NPVariant* arguments, uint32_t argumentCount, N argumentList.append(m_objectMap->convertNPVariantToJSValue(exec, m_objectMap->globalObject(), arguments[i])); exec->globalData().timeoutChecker.start(); - JSValue value = JSC::construct(exec, m_jsObject, constructType, constructData, argumentList); + JSValue value = JSC::construct(exec, m_jsObject.get(), constructType, constructData, argumentList); exec->globalData().timeoutChecker.stop(); // Convert and return the new object. @@ -292,7 +293,7 @@ bool NPJSObject::invoke(ExecState* exec, JSGlobalObject* globalObject, JSValue f argumentList.append(m_objectMap->convertNPVariantToJSValue(exec, globalObject, arguments[i])); exec->globalData().timeoutChecker.start(); - JSValue value = JSC::call(exec, function, callType, callData, m_jsObject, argumentList); + JSValue value = JSC::call(exec, function, callType, callData, m_jsObject.get(), argumentList); exec->globalData().timeoutChecker.stop(); // Convert and return the result of the function call. diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.h index 3518221..796f1c3 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.h @@ -26,13 +26,16 @@ #ifndef NPJSObject_h #define NPJSObject_h -#include <JavaScriptCore/Protect.h> +#include <JavaScriptCore/Global.h> #include <WebCore/npruntime_internal.h> #include <wtf/Noncopyable.h> namespace JSC { - class JSGlobalObject; - class JSObject; + +class JSGlobalData; +class JSGlobalObject; +class JSObject; + } namespace WebKit { @@ -43,7 +46,7 @@ class NPRuntimeObjectMap; class NPJSObject : public NPObject { WTF_MAKE_NONCOPYABLE(NPJSObject); public: - static NPJSObject* create(NPRuntimeObjectMap* objectMap, JSC::JSObject* jsObject); + static NPJSObject* create(JSC::JSGlobalData&, NPRuntimeObjectMap*, JSC::JSObject*); JSC::JSObject* jsObject() const { return m_jsObject.get(); } @@ -59,7 +62,7 @@ private: NPJSObject(); ~NPJSObject(); - void initialize(NPRuntimeObjectMap*, JSC::JSObject* jsObject); + void initialize(JSC::JSGlobalData&, NPRuntimeObjectMap*, JSC::JSObject*); bool hasMethod(NPIdentifier methodName); bool invoke(NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result); @@ -87,7 +90,7 @@ private: static bool NP_Construct(NPObject*, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result); NPRuntimeObjectMap* m_objectMap; - JSC::ProtectedPtr<JSC::JSObject> m_jsObject; + JSC::Global<JSC::JSObject> m_jsObject; }; } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp index 0a96ad7..f6c0057 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp @@ -29,12 +29,12 @@ #include "JSNPObject.h" #include "NPJSObject.h" #include "NPRuntimeUtilities.h" -#include "NotImplemented.h" #include "PluginView.h" #include <JavaScriptCore/Error.h> #include <JavaScriptCore/JSLock.h> #include <JavaScriptCore/SourceCode.h> #include <WebCore/Frame.h> +#include <WebCore/NotImplemented.h> using namespace JSC; using namespace WebCore; @@ -58,7 +58,7 @@ NPRuntimeObjectMap::PluginProtector::~PluginProtector() { } -NPObject* NPRuntimeObjectMap::getOrCreateNPObject(JSObject* jsObject) +NPObject* NPRuntimeObjectMap::getOrCreateNPObject(JSGlobalData& globalData, JSObject* jsObject) { // If this is a JSNPObject, we can just get its underlying NPObject. if (jsObject->classInfo() == &JSNPObject::s_info) { @@ -75,7 +75,7 @@ NPObject* NPRuntimeObjectMap::getOrCreateNPObject(JSObject* jsObject) return npJSObject; } - NPJSObject* npJSObject = NPJSObject::create(this, jsObject); + NPJSObject* npJSObject = NPJSObject::create(globalData, this, jsObject); m_npJSObjects.set(jsObject, npJSObject); return npJSObject; @@ -172,7 +172,7 @@ void NPRuntimeObjectMap::convertJSValueToNPVariant(ExecState* exec, JSValue valu } if (value.isObject()) { - NPObject* npObject = getOrCreateNPObject(asObject(value)); + NPObject* npObject = getOrCreateNPObject(exec->globalData(), asObject(value)); OBJECT_TO_NPVARIANT(npObject, variant); return; } @@ -182,14 +182,14 @@ void NPRuntimeObjectMap::convertJSValueToNPVariant(ExecState* exec, JSValue valu bool NPRuntimeObjectMap::evaluate(NPObject* npObject, const String&scriptString, NPVariant* result) { - ProtectedPtr<JSGlobalObject> globalObject = this->globalObject(); + Global<JSGlobalObject> globalObject(this->globalObject()->globalData(), this->globalObject()); if (!globalObject) return false; ExecState* exec = globalObject->globalExec(); JSLock lock(SilenceAssertionsOnly); - JSValue thisValue = getOrCreateJSObject(globalObject, npObject); + JSValue thisValue = getOrCreateJSObject(globalObject.get(), npObject); globalObject->globalData().timeoutChecker.start(); Completion completion = JSC::evaluate(exec, globalObject->globalScopeChain(), makeSource(UString(scriptString.impl())), thisValue); diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h index a11c354..d13e1fe 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h @@ -34,6 +34,7 @@ typedef struct _NPVariant NPVariant; namespace JSC { class ExecState; + class JSGlobalData; class JSGlobalObject; class JSObject; class JSValue; @@ -61,7 +62,7 @@ public: // Returns an NPObject that wraps the given JSObject object. If there is already an NPObject that wraps this JSObject, it will // retain it and return it. - NPObject* getOrCreateNPObject(JSC::JSObject*); + NPObject* getOrCreateNPObject(JSC::JSGlobalData&, JSC::JSObject*); void npJSObjectDestroyed(NPJSObject*); // Returns a JSObject object that wraps the given NPObject. diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp index 5f8ee5c..679de6f 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp @@ -28,9 +28,10 @@ #include "NPRuntimeUtilities.h" #include "NetscapePlugin.h" -#include "NotImplemented.h" +#include "PluginController.h" #include <WebCore/HTTPHeaderMap.h> #include <WebCore/IdentifierRep.h> +#include <WebCore/NotImplemented.h> #include <WebCore/SharedBuffer.h> #include <utility> @@ -39,6 +40,18 @@ using namespace std; namespace WebKit { +// Helper class for delaying destruction of a plug-in. +class PluginDestructionProtector { +public: + explicit PluginDestructionProtector(NetscapePlugin* plugin) + : m_protector(static_cast<Plugin*>(plugin)->controller()) + { + } + +private: + PluginController::PluginDestructionProtector m_protector; +}; + static bool startsWithBlankLine(const char* bytes, unsigned length) { return length > 0 && bytes[0] == '\n'; @@ -401,13 +414,18 @@ static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) switch (variable) { case NPNVWindowNPObject: { RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); NPObject* windowNPObject = plugin->windowScriptNPObject(); + if (!windowNPObject) + return NPERR_GENERIC_ERROR; + *(NPObject**)value = windowNPObject; break; } case NPNVPluginElementNPObject: { RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); NPObject* pluginElementNPObject = plugin->pluginElementNPObject(); *(NPObject**)value = pluginElementNPObject; @@ -465,6 +483,18 @@ static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) case NPNVSupportsWindowless: *(NPBool*)value = true; break; +#elif PLUGIN_ARCHITECTURE(X11) + case NPNVToolkit: { + const uint32_t expectedGTKToolKitVersion = 2; + + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + if (plugin->quirks().contains(PluginQuirks::RequiresGTKToolKit)) { + *reinterpret_cast<uint32_t*>(value) = expectedGTKToolKitVersion; + break; + } + + return NPERR_GENERIC_ERROR; + } #endif default: notImplemented(); @@ -605,45 +635,62 @@ static bool NPN_InvokeDefault(NPP, NPObject *npObject, const NPVariant* argument static bool NPN_Evaluate(NPP npp, NPObject *npObject, NPString *script, NPVariant* result) { RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + String scriptString = String::fromUTF8WithLatin1Fallback(script->UTF8Characters, script->UTF8Length); return plugin->evaluate(npObject, scriptString, result); } -static bool NPN_GetProperty(NPP, NPObject* npObject, NPIdentifier propertyName, NPVariant* result) +static bool NPN_GetProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName, NPVariant* result) { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + if (npObject->_class->getProperty) return npObject->_class->getProperty(npObject, propertyName, result); return false; } -static bool NPN_SetProperty(NPP, NPObject* npObject, NPIdentifier propertyName, const NPVariant* value) +static bool NPN_SetProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName, const NPVariant* value) { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + if (npObject->_class->setProperty) return npObject->_class->setProperty(npObject, propertyName, value); return false; } -static bool NPN_RemoveProperty(NPP, NPObject* npObject, NPIdentifier propertyName) +static bool NPN_RemoveProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName) { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + if (npObject->_class->removeProperty) return npObject->_class->removeProperty(npObject, propertyName); return false; } -static bool NPN_HasProperty(NPP, NPObject* npObject, NPIdentifier propertyName) +static bool NPN_HasProperty(NPP npp, NPObject* npObject, NPIdentifier propertyName) { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + if (npObject->_class->hasProperty) return npObject->_class->hasProperty(npObject, propertyName); return false; } -static bool NPN_HasMethod(NPP, NPObject* npObject, NPIdentifier methodName) +static bool NPN_HasMethod(NPP npp, NPObject* npObject, NPIdentifier methodName) { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + if (npObject->_class->hasMethod) return npObject->_class->hasMethod(npObject, methodName); @@ -672,8 +719,11 @@ static void NPN_PopPopupsEnabledState(NPP npp) plugin->popPopupsEnabledState(); } -static bool NPN_Enumerate(NPP, NPObject* npObject, NPIdentifier** identifiers, uint32_t* identifierCount) +static bool NPN_Enumerate(NPP npp, NPObject* npObject, NPIdentifier** identifiers, uint32_t* identifierCount) { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + if (NP_CLASS_STRUCT_VERSION_HAS_ENUM(npObject->_class) && npObject->_class->enumerate) return npObject->_class->enumerate(npObject, identifiers, identifierCount); @@ -685,8 +735,11 @@ static void NPN_PluginThreadAsyncCall(NPP instance, void (*func) (void*), void* notImplemented(); } -static bool NPN_Construct(NPP, NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) +static bool NPN_Construct(NPP npp, NPObject* npObject, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + PluginDestructionProtector protector(plugin.get()); + if (NP_CLASS_STRUCT_VERSION_HAS_CTOR(npObject->_class) && npObject->_class->construct) return npObject->_class->construct(npObject, arguments, argumentCount, result); @@ -716,7 +769,8 @@ static NPError NPN_GetValueForURL(NPP npp, NPNURLVariable variable, const char* switch (variable) { case NPNURLVCookie: { RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); - + PluginDestructionProtector protector(plugin.get()); + String cookies = plugin->cookiesForURL(makeURLString(url)); if (cookies.isNull()) return NPERR_GENERIC_ERROR; @@ -726,7 +780,8 @@ static NPError NPN_GetValueForURL(NPP npp, NPNURLVariable variable, const char* case NPNURLVProxy: { RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); - + PluginDestructionProtector protector(plugin.get()); + String proxies = plugin->proxiesForURL(makeURLString(url)); if (proxies.isNull()) return NPERR_GENERIC_ERROR; @@ -744,7 +799,8 @@ static NPError NPN_SetValueForURL(NPP npp, NPNURLVariable variable, const char* switch (variable) { case NPNURLVCookie: { RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); - + PluginDestructionProtector protector(plugin.get()); + plugin->setCookiesForURL(makeURLString(url), String(value, len)); return NPERR_NO_ERROR; } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp index e746d5a..7e9b059 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp @@ -29,6 +29,7 @@ #include "NPRuntimeObjectMap.h" #include "NetscapePluginStream.h" #include "PluginController.h" +#include "ShareableBitmap.h" #include <WebCore/GraphicsContext.h> #include <WebCore/HTTPHeaderMap.h> #include <WebCore/IntRect.h> @@ -479,6 +480,23 @@ void NetscapePlugin::paint(GraphicsContext* context, const IntRect& dirtyRect) platformPaint(context, dirtyRect); } +PassRefPtr<ShareableBitmap> NetscapePlugin::snapshot() +{ + if (!supportsSnapshotting() || m_frameRect.isEmpty()) + return 0; + + ASSERT(m_isStarted); + + RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(m_frameRect.size()); + OwnPtr<GraphicsContext> context = bitmap->createGraphicsContext(); + + context->translate(-m_frameRect.x(), -m_frameRect.y()); + + platformPaint(context.get(), m_frameRect, true); + + return bitmap.release(); +} + void NetscapePlugin::geometryDidChange(const IntRect& frameRect, const IntRect& clipRect) { ASSERT(m_isStarted); @@ -672,6 +690,14 @@ void NetscapePlugin::privateBrowsingStateChanged(bool privateBrowsingEnabled) NPP_SetValue(NPNVprivateModeBool, &value); } +bool NetscapePlugin::supportsSnapshotting() const +{ +#if PLATFORM(MAC) + return m_pluginModule && m_pluginModule->pluginQuirks().contains(PluginQuirks::SupportsSnapshotting); +#endif + return false; +} + PluginController* NetscapePlugin::controller() { return m_pluginController; diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h index e807beb..e865d93 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h @@ -70,6 +70,8 @@ public: HWND containingWindow() const; #endif + PluginQuirks quirks() const { return m_pluginModule->pluginQuirks(); } + void invalidate(const NPRect*); static const char* userAgent(NPP); void loadURL(const String& method, const String& urlString, const String& target, const WebCore::HTTPHeaderMap& headerFields, @@ -126,7 +128,7 @@ private: void platformDestroy(); bool platformInvalidate(const WebCore::IntRect&); void platformGeometryDidChange(); - void platformPaint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect); + void platformPaint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect, bool isSnapshot = false); bool platformHandleMouseEvent(const WebMouseEvent&); bool platformHandleWheelEvent(const WebWheelEvent&); @@ -139,6 +141,7 @@ private: virtual bool initialize(PluginController*, const Parameters&); virtual void destroy(); virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect); + virtual PassRefPtr<ShareableBitmap> snapshot(); #if PLATFORM(MAC) virtual PlatformLayer* pluginLayer(); #endif @@ -176,6 +179,8 @@ private: virtual void privateBrowsingStateChanged(bool); + bool supportsSnapshotting() const; + virtual PluginController* controller(); PluginController* m_pluginController; diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/gtk/NetscapePluginGtk.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/gtk/NetscapePluginGtk.cpp index 2b734fd..f7c9440 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/gtk/NetscapePluginGtk.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/gtk/NetscapePluginGtk.cpp @@ -27,7 +27,7 @@ #include "config.h" #include "NetscapePlugin.h" -#include "NotImplemented.h" +#include <WebCore/NotImplemented.h> using namespace WebCore; @@ -55,7 +55,7 @@ void NetscapePlugin::platformGeometryDidChange() notImplemented(); } -void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect) +void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect, bool) { notImplemented(); } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm b/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm index 46671b8..2a33008 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm @@ -373,7 +373,7 @@ static EventModifiers modifiersForEvent(const WebEvent& event) #endif -void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect) +void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect, bool isSnapshot) { CGContextRef platformContext = context->platformContext(); @@ -383,7 +383,7 @@ void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirt switch (m_eventModel) { case NPEventModelCocoa: { // Don't send draw events when we're using the Core Animation drawing model. - if (m_drawingModel == NPDrawingModelCoreAnimation) + if (!isSnapshot && m_drawingModel == NPDrawingModelCoreAnimation) return; NPCocoaEvent event = initializeEvent(NPCocoaEventDrawRect); @@ -830,9 +830,8 @@ void NetscapePlugin::windowVisibilityChanged(bool) uint64_t NetscapePlugin::pluginComplexTextInputIdentifier() const { - // This is never called for NetscapePlugin. - ASSERT_NOT_REACHED(); - return 0; + // Just return a dummy value; this is only called for in-process plug-ins, which we don't support on Mac. + return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this)); } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/qt/NetscapePluginQt.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/qt/NetscapePluginQt.cpp index 1ede2c3..581dcf3 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/qt/NetscapePluginQt.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/qt/NetscapePluginQt.cpp @@ -27,9 +27,9 @@ #include "config.h" #include "NetscapePlugin.h" -#include "NotImplemented.h" #include "WebEvent.h" #include <WebCore/GraphicsContext.h> +#include <WebCore/NotImplemented.h> using namespace WebCore; @@ -57,7 +57,7 @@ void NetscapePlugin::platformGeometryDidChange() notImplemented(); } -void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect) +void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect, bool) { notImplemented(); } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/qt/PluginProxyQt.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/qt/PluginProxyQt.cpp new file mode 100644 index 0000000..7af1784 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/qt/PluginProxyQt.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2011 Nokia Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PluginProxy.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include <WebCore/NotImplemented.h> + +namespace WebKit { + +bool PluginProxy::needsBackingStore() const +{ + notImplemented(); + return true; +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/win/NetscapePluginWin.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/win/NetscapePluginWin.cpp index e713f83..5fbe32c 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/win/NetscapePluginWin.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/win/NetscapePluginWin.cpp @@ -26,11 +26,11 @@ #include "config.h" #include "NetscapePlugin.h" -#include "NotImplemented.h" #include "PluginController.h" #include "WebEvent.h" #include <WebCore/GraphicsContext.h> #include <WebCore/LocalWindowsContext.h> +#include <WebCore/NotImplemented.h> using namespace WebCore; @@ -135,7 +135,7 @@ void NetscapePlugin::platformGeometryDidChange() ::MoveWindow(m_window, m_frameRect.x(), m_frameRect.y(), m_frameRect.width(), m_frameRect.height(), TRUE); } -void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect) +void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect, bool) { // FIXME: Call SetWindow here if we haven't called it yet (see r59904). diff --git a/Source/WebKit2/WebProcess/Plugins/Plugin.h b/Source/WebKit2/WebProcess/Plugins/Plugin.h index 6f20159..6afeb5c 100644 --- a/Source/WebKit2/WebProcess/Plugins/Plugin.h +++ b/Source/WebKit2/WebProcess/Plugins/Plugin.h @@ -45,6 +45,7 @@ namespace WebCore { namespace WebKit { +class ShareableBitmap; class WebKeyboardEvent; class WebMouseEvent; class WebWheelEvent; @@ -76,6 +77,9 @@ public: // dirty rect are in window coordinates. The context is saved/restored by the caller. virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect) = 0; + // Tells the plug-in to draw itself into a bitmap, and return that. + virtual PassRefPtr<ShareableBitmap> snapshot() = 0; + #if PLATFORM(MAC) // If a plug-in is using the Core Animation drawing model, this returns its plug-in layer. virtual PlatformLayer* pluginLayer() = 0; diff --git a/Source/WebKit2/WebProcess/Plugins/PluginController.h b/Source/WebKit2/WebProcess/Plugins/PluginController.h index 9dc8ec3..a104139 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginController.h +++ b/Source/WebKit2/WebProcess/Plugins/PluginController.h @@ -108,6 +108,30 @@ public: // Returns whether private browsing is enabled. virtual bool isPrivateBrowsingEnabled() = 0; + // Increments a counter that prevents the plug-in from being destroyed. + virtual void protectPluginFromDestruction() = 0; + + // Decrements a counter that, when it reaches 0, stops preventing the plug-in from being destroyed. + virtual void unprotectPluginFromDestruction() = 0; + + // Helper class for delaying destruction of a plug-in. + class PluginDestructionProtector { + public: + explicit PluginDestructionProtector(PluginController* pluginController) + : m_pluginController(pluginController) + { + m_pluginController->protectPluginFromDestruction(); + } + + ~PluginDestructionProtector() + { + m_pluginController->unprotectPluginFromDestruction(); + } + + private: + PluginController* m_pluginController; + }; + protected: virtual ~PluginController() { } }; diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp b/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp index 551e458..f267d9e 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp +++ b/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp @@ -117,6 +117,8 @@ void PluginProxy::destroy() m_connection->connection()->sendSync(Messages::WebProcessConnection::DestroyPlugin(m_pluginInstanceID), Messages::WebProcessConnection::DestroyPlugin::Reply(), 0); m_isStarted = false; + m_pluginController = 0; + m_connection->removePluginProxy(this); } @@ -148,6 +150,16 @@ void PluginProxy::paint(GraphicsContext* graphicsContext, const IntRect& dirtyRe } } +PassRefPtr<ShareableBitmap> PluginProxy::snapshot() +{ + IntSize bufferSize; + SharedMemory::Handle snapshotStoreHandle; + m_connection->connection()->sendSync(Messages::PluginControllerProxy::Snapshot(), Messages::PluginControllerProxy::Snapshot::Reply(bufferSize, snapshotStoreHandle), m_pluginInstanceID); + + RefPtr<ShareableBitmap> snapshotBuffer = ShareableBitmap::create(bufferSize, snapshotStoreHandle); + return snapshotBuffer.release(); +} + void PluginProxy::geometryDidChange(const IntRect& frameRect, const IntRect& clipRect) { ASSERT(m_isStarted); @@ -394,6 +406,8 @@ void PluginProxy::getPluginElementNPObject(uint64_t& pluginElementNPObjectID) void PluginProxy::evaluate(const NPVariantData& npObjectAsVariantData, const String& scriptString, bool allowPopups, bool& returnValue, NPVariantData& resultData) { + PluginController::PluginDestructionProtector protector(m_pluginController); + NPVariant npObjectAsVariant = m_connection->npRemoteObjectMap()->npVariantDataToNPVariant(npObjectAsVariantData); ASSERT(NPVARIANT_IS_OBJECT(npObjectAsVariant)); diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProxy.h b/Source/WebKit2/WebProcess/Plugins/PluginProxy.h index 9be7bd1..4fe99a7 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProxy.h +++ b/Source/WebKit2/WebProcess/Plugins/PluginProxy.h @@ -64,6 +64,7 @@ private: virtual bool initialize(PluginController*, const Parameters&); virtual void destroy(); virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect); + virtual PassRefPtr<ShareableBitmap> snapshot(); #if PLATFORM(MAC) virtual PlatformLayer* pluginLayer(); #endif diff --git a/Source/WebKit2/WebProcess/Plugins/PluginView.cpp b/Source/WebKit2/WebProcess/Plugins/PluginView.cpp index 8ac7d3a..3b1629d 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginView.cpp +++ b/Source/WebKit2/WebProcess/Plugins/PluginView.cpp @@ -28,6 +28,7 @@ #include "NPRuntimeUtilities.h" #include "Plugin.h" +#include "ShareableBitmap.h" #include "WebEvent.h" #include "WebPage.h" #include "WebPageProxyMessages.h" @@ -505,25 +506,36 @@ void PluginView::setFrameRect(const WebCore::IntRect& rect) viewGeometryDidChange(); } +void PluginView::setBoundsSize(const WebCore::IntSize& size) +{ + Widget::setBoundsSize(size); + m_boundsSize = size; + viewGeometryDidChange(); +} + void PluginView::paint(GraphicsContext* context, const IntRect& dirtyRect) { if (context->paintingDisabled() || !m_plugin || !m_isInitialized) return; IntRect dirtyRectInWindowCoordinates = parent()->contentsToWindow(dirtyRect); - IntRect paintRectInWindowCoordinates = intersection(dirtyRectInWindowCoordinates, clipRectInWindowCoordinates()); if (paintRectInWindowCoordinates.isEmpty()) return; - // context is in document coordinates. Translate it to window coordinates. - IntPoint documentOriginInWindowCoordinates = parent()->contentsToWindow(IntPoint()); - context->save(); - context->translate(-documentOriginInWindowCoordinates.x(), -documentOriginInWindowCoordinates.y()); - - m_plugin->paint(context, paintRectInWindowCoordinates); - - context->restore(); + if (m_snapshot) + m_snapshot->paint(*context, frameRect().location(), m_snapshot->bounds()); + else { + // The plugin is given a frame rect which is parent()->contentsToWindow(frameRect()), + // and un-translates by the its origin when painting. The current CTM reflects + // this widget's frame is its parent (the document), so we have to offset the CTM by + // the document's window coordinates. + IntPoint documentOriginInWindowCoordinates = parent()->contentsToWindow(IntPoint()); + context->save(); + context->translate(-documentOriginInWindowCoordinates.x(), -documentOriginInWindowCoordinates.y()); + m_plugin->paint(context, paintRectInWindowCoordinates); + context->restore(); + } } void PluginView::frameRectsChanged() @@ -577,7 +589,20 @@ void PluginView::handleEvent(Event* event) if (didHandleEvent) event->setDefaultHandled(); } - + +void PluginView::notifyWidget(WidgetNotification notification) +{ + switch (notification) { + case WillPaintFlattened: + if (m_plugin && m_isInitialized) + m_snapshot = m_plugin->snapshot(); + break; + case DidPaintFlattened: + m_snapshot = nullptr; + break; + } +} + void PluginView::viewGeometryDidChange() { if (!m_isInitialized || !m_plugin || !parent()) @@ -585,7 +610,7 @@ void PluginView::viewGeometryDidChange() // Get the frame rect in window coordinates. IntRect frameRectInWindowCoordinates = parent()->contentsToWindow(frameRect()); - + frameRectInWindowCoordinates.setSize(m_boundsSize); m_plugin->geometryDidChange(frameRectInWindowCoordinates, clipRectInWindowCoordinates()); } @@ -595,6 +620,7 @@ IntRect PluginView::clipRectInWindowCoordinates() const // Get the frame rect in window coordinates. IntRect frameRectInWindowCoordinates = parent()->contentsToWindow(frameRect()); + frameRectInWindowCoordinates.setSize(m_boundsSize); // Get the window clip rect for the enclosing layer (in window coordinates). RenderLayer* layer = m_pluginElement->renderer()->enclosingLayer(); @@ -712,7 +738,7 @@ void PluginView::performJavaScriptURLRequest(URLRequest* request) bool oldAllowPopups = frame->script()->allowPopupsFromPlugin(); frame->script()->setAllowPopupsFromPlugin(request->allowPopups()); - ScriptValue result = m_pluginElement->document()->frame()->script()->executeScript(jsString); + ScriptValue result = frame->script()->executeScript(jsString); frame->script()->setAllowPopupsFromPlugin(oldAllowPopups); @@ -720,7 +746,7 @@ void PluginView::performJavaScriptURLRequest(URLRequest* request) if (!plugin->controller()) return; - ScriptState* scriptState = m_pluginElement->document()->frame()->script()->globalObject(pluginWorld())->globalExec(); + ScriptState* scriptState = frame->script()->globalObject(pluginWorld())->globalExec(); String resultString; result.getString(scriptState, resultString); @@ -883,7 +909,7 @@ NPObject* PluginView::windowScriptNPObject() // FIXME: Handle JavaScript being disabled. ASSERT(frame()->script()->canExecuteScripts(NotAboutToExecuteScript)); - return m_npRuntimeObjectMap.getOrCreateNPObject(frame()->script()->windowShell(pluginWorld())->window()); + return m_npRuntimeObjectMap.getOrCreateNPObject(*pluginWorld()->globalData(), frame()->script()->windowShell(pluginWorld())->window()); } NPObject* PluginView::pluginElementNPObject() @@ -895,7 +921,7 @@ NPObject* PluginView::pluginElementNPObject() JSObject* object = frame()->script()->jsObjectForPluginElement(m_pluginElement.get()); ASSERT(object); - return m_npRuntimeObjectMap.getOrCreateNPObject(object); + return m_npRuntimeObjectMap.getOrCreateNPObject(*pluginWorld()->globalData(), object); } bool PluginView::evaluate(NPObject* npObject, const String& scriptString, NPVariant* result, bool allowPopups) @@ -1007,6 +1033,18 @@ bool PluginView::isPrivateBrowsingEnabled() return settings->privateBrowsingEnabled(); } +void PluginView::protectPluginFromDestruction() +{ + if (!m_isBeingDestroyed) + ref(); +} + +void PluginView::unprotectPluginFromDestruction() +{ + if (!m_isBeingDestroyed) + deref(); +} + void PluginView::didFinishLoad(WebFrame* webFrame) { RefPtr<URLRequest> request = m_pendingFrameLoads.take(webFrame); diff --git a/Source/WebKit2/WebProcess/Plugins/PluginView.h b/Source/WebKit2/WebProcess/Plugins/PluginView.h index dca3a62..a30926f 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginView.h +++ b/Source/WebKit2/WebProcess/Plugins/PluginView.h @@ -104,12 +104,14 @@ private: // WebCore::Widget virtual void setFrameRect(const WebCore::IntRect&); + virtual void setBoundsSize(const WebCore::IntSize&); virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect&); virtual void invalidateRect(const WebCore::IntRect&); virtual void setFocus(bool); virtual void frameRectsChanged(); virtual void setParent(WebCore::ScrollView*); virtual void handleEvent(WebCore::Event*); + virtual void notifyWidget(WebCore::WidgetNotification); // WebCore::MediaCanStartListener virtual void mediaCanStart(); @@ -138,6 +140,8 @@ private: virtual String cookiesForURL(const String&); virtual void setCookiesForURL(const String& urlString, const String& cookieString); virtual bool isPrivateBrowsingEnabled(); + virtual void protectPluginFromDestruction(); + virtual void unprotectPluginFromDestruction(); // WebFrame::LoadListener virtual void didFinishLoad(WebFrame*); @@ -179,6 +183,9 @@ private: WebCore::ResourceResponse m_manualStreamResponse; WebCore::ResourceError m_manualStreamError; RefPtr<WebCore::SharedBuffer> m_manualStreamData; + + RefPtr<ShareableBitmap> m_snapshot; + WebCore::IntSize m_boundsSize; }; } // namespace WebKit |