diff options
Diffstat (limited to 'Source/WebKit2/WebProcess/Plugins/Netscape')
17 files changed, 950 insertions, 512 deletions
diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp index d816cdce8..aeda99ddb 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -43,7 +43,7 @@ namespace WebKit { STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSNPMethod); -const ClassInfo JSNPMethod::s_info = { "NPMethod", &InternalFunction::s_info, 0, 0, CREATE_METHOD_TABLE(JSNPMethod) }; +const ClassInfo JSNPMethod::s_info = { "NPMethod", &InternalFunction::s_info, 0, CREATE_METHOD_TABLE(JSNPMethod) }; JSNPMethod::JSNPMethod(JSGlobalObject* globalObject, Structure* structure, NPIdentifier npIdentifier) : InternalFunction(globalObject->vm(), structure) @@ -54,17 +54,20 @@ JSNPMethod::JSNPMethod(JSGlobalObject* globalObject, Structure* structure, NPIde void JSNPMethod::finishCreation(VM& vm, const String& name) { Base::finishCreation(vm, name); - ASSERT(inherits(info())); + ASSERT(inherits(vm, info())); } static EncodedJSValue JSC_HOST_CALL callMethod(ExecState* exec) { - JSNPMethod* jsNPMethod = jsCast<JSNPMethod*>(exec->callee()); + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); - JSValue thisValue = exec->hostThisValue(); + JSNPMethod* jsNPMethod = jsCast<JSNPMethod*>(exec->jsCallee()); + + JSValue thisValue = exec->thisValue(); // Check if we're calling a method on the plug-in script object. - if (thisValue.inherits(JSHTMLElement::info())) { + if (thisValue.inherits(vm, JSHTMLElement::info())) { JSHTMLElement* element = jsCast<JSHTMLElement*>(asObject(thisValue)); // Try to get the script object from the element @@ -72,19 +75,19 @@ static EncodedJSValue JSC_HOST_CALL callMethod(ExecState* exec) thisValue = scriptObject; } - if (thisValue.inherits(JSNPObject::info())) { + if (thisValue.inherits(vm, JSNPObject::info())) { JSNPObject* jsNPObject = jsCast<JSNPObject*>(asObject(thisValue)); return JSValue::encode(jsNPObject->callMethod(exec, jsNPMethod->npIdentifier())); } - return throwVMTypeError(exec); + return throwVMTypeError(exec, scope); } CallType JSNPMethod::getCallData(JSCell*, CallData& callData) { callData.native.function = callMethod; - return CallTypeHost; + return CallType::Host; } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp index 9674ca3e9..d68974d0b 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,10 +32,13 @@ #include "NPJSObject.h" #include "NPRuntimeObjectMap.h" #include "NPRuntimeUtilities.h" +#include <JavaScriptCore/AuxiliaryBarrierInlines.h> #include <JavaScriptCore/Error.h> +#include <JavaScriptCore/IdentifierInlines.h> #include <JavaScriptCore/JSGlobalObject.h> #include <JavaScriptCore/JSLock.h> #include <JavaScriptCore/ObjectPrototype.h> +#include <WebCore/CommonVM.h> #include <WebCore/IdentifierRep.h> #include <WebCore/JSDOMWindowBase.h> #include <wtf/Assertions.h> @@ -49,12 +52,13 @@ namespace WebKit { static NPIdentifier npIdentifierFromIdentifier(PropertyName propertyName) { String name(propertyName.publicName()); + // If the propertyName is Symbol. if (name.isNull()) - return 0; + return nullptr; return static_cast<NPIdentifier>(IdentifierRep::get(name.utf8().data())); } -const ClassInfo JSNPObject::s_info = { "NPObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSNPObject) }; +const ClassInfo JSNPObject::s_info = { "NPObject", &Base::s_info, 0, CREATE_METHOD_TABLE(JSNPObject) }; JSNPObject::JSNPObject(JSGlobalObject* globalObject, Structure* structure, NPRuntimeObjectMap* objectMap, NPObject* npObject) : JSDestructibleObject(globalObject->vm(), structure) @@ -66,8 +70,9 @@ JSNPObject::JSNPObject(JSGlobalObject* globalObject, Structure* structure, NPRun void JSNPObject::finishCreation(JSGlobalObject* globalObject) { - Base::finishCreation(globalObject->vm()); - ASSERT(inherits(info())); + VM& vm = globalObject->vm(); + Base::finishCreation(vm); + ASSERT(inherits(vm, info())); // We should never have an NPJSObject inside a JSNPObject. ASSERT(!NPJSObject::isNPJSObject(m_npObject)); @@ -89,7 +94,6 @@ void JSNPObject::destroy(JSCell* cell) void JSNPObject::invalidate() { ASSERT(m_npObject); - ASSERT_GC_OBJECT_INHERITS(this, info()); releaseNPObject(m_npObject); m_npObject = 0; @@ -106,9 +110,16 @@ NPObject* JSNPObject::leakNPObject() JSValue JSNPObject::callMethod(ExecState* exec, NPIdentifier methodName) { - ASSERT_GC_OBJECT_INHERITS(this, info()); + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + ASSERT_THIS_GC_OBJECT_INHERITS(info()); if (!m_npObject) - return throwInvalidAccessError(exec); + return throwInvalidAccessError(exec, scope); + + // If the propertyName is symbol. + if (!methodName) + return jsUndefined(); size_t argumentCount = exec->argumentCount(); Vector<NPVariant, 8> arguments(argumentCount); @@ -127,17 +138,17 @@ JSValue JSNPObject::callMethod(ExecState* exec, NPIdentifier methodName) VOID_TO_NPVARIANT(result); { - JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); + JSLock::DropAllLocks dropAllLocks(commonVM()); returnValue = m_npObject->_class->invoke(m_npObject, methodName, arguments.data(), argumentCount, &result); NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); } - // Release all arguments; + // Release all arguments. for (size_t i = 0; i < argumentCount; ++i) releaseNPVariantValue(&arguments[i]); if (!returnValue) - exec->vm().throwException(exec, createError(exec, "Error calling method on NPObject.")); + throwException(exec, scope, createError(exec, "Error calling method on NPObject.")); JSValue propertyValue = m_objectMap->convertNPVariantToJSValue(exec, globalObject(), result); releaseNPVariantValue(&result); @@ -146,9 +157,12 @@ JSValue JSNPObject::callMethod(ExecState* exec, NPIdentifier methodName) JSC::JSValue JSNPObject::callObject(JSC::ExecState* exec) { - ASSERT_GC_OBJECT_INHERITS(this, info()); + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + ASSERT_THIS_GC_OBJECT_INHERITS(info()); if (!m_npObject) - return throwInvalidAccessError(exec); + return throwInvalidAccessError(exec, scope); size_t argumentCount = exec->argumentCount(); Vector<NPVariant, 8> arguments(argumentCount); @@ -167,7 +181,7 @@ JSC::JSValue JSNPObject::callObject(JSC::ExecState* exec) VOID_TO_NPVARIANT(result); { - JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); + JSLock::DropAllLocks dropAllLocks(commonVM()); returnValue = m_npObject->_class->invokeDefault(m_npObject, arguments.data(), argumentCount, &result); NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); } @@ -177,7 +191,7 @@ JSC::JSValue JSNPObject::callObject(JSC::ExecState* exec) releaseNPVariantValue(&arguments[i]); if (!returnValue) - exec->vm().throwException(exec, createError(exec, "Error calling method on NPObject.")); + throwException(exec, scope, createError(exec, "Error calling method on NPObject.")); JSValue propertyValue = m_objectMap->convertNPVariantToJSValue(exec, globalObject(), result); releaseNPVariantValue(&result); @@ -186,9 +200,12 @@ JSC::JSValue JSNPObject::callObject(JSC::ExecState* exec) JSValue JSNPObject::callConstructor(ExecState* exec) { - ASSERT_GC_OBJECT_INHERITS(this, info()); + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + ASSERT_THIS_GC_OBJECT_INHERITS(info()); if (!m_npObject) - return throwInvalidAccessError(exec); + return throwInvalidAccessError(exec, scope); size_t argumentCount = exec->argumentCount(); Vector<NPVariant, 8> arguments(argumentCount); @@ -207,13 +224,13 @@ JSValue JSNPObject::callConstructor(ExecState* exec) VOID_TO_NPVARIANT(result); { - JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); + JSLock::DropAllLocks dropAllLocks(commonVM()); returnValue = m_npObject->_class->construct(m_npObject, arguments.data(), argumentCount, &result); NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); } if (!returnValue) - exec->vm().throwException(exec, createError(exec, "Error calling method on NPObject.")); + throwException(exec, scope, createError(exec, "Error calling method on NPObject.")); JSValue value = m_objectMap->convertNPVariantToJSValue(exec, globalObject(), result); releaseNPVariantValue(&result); @@ -222,8 +239,8 @@ JSValue JSNPObject::callConstructor(ExecState* exec) static EncodedJSValue JSC_HOST_CALL callNPJSObject(ExecState* exec) { - JSObject* object = exec->callee(); - ASSERT(object->inherits(JSNPObject::info())); + JSObject* object = exec->jsCallee(); + ASSERT(object->inherits(exec->vm(), JSNPObject::info())); return JSValue::encode(jsCast<JSNPObject*>(object)->callObject(exec)); } @@ -233,16 +250,16 @@ JSC::CallType JSNPObject::getCallData(JSC::JSCell* cell, JSC::CallData& callData JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); if (!thisObject->m_npObject || !thisObject->m_npObject->_class->invokeDefault) - return CallTypeNone; + return CallType::None; callData.native.function = callNPJSObject; - return CallTypeHost; + return CallType::Host; } static EncodedJSValue JSC_HOST_CALL constructWithConstructor(ExecState* exec) { - JSObject* constructor = exec->callee(); - ASSERT(constructor->inherits(JSNPObject::info())); + JSObject* constructor = exec->jsCallee(); + ASSERT(constructor->inherits(exec->vm(), JSNPObject::info())); return JSValue::encode(jsCast<JSNPObject*>(constructor)->callConstructor(exec)); } @@ -252,22 +269,28 @@ ConstructType JSNPObject::getConstructData(JSCell* cell, ConstructData& construc JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); if (!thisObject->m_npObject || !thisObject->m_npObject->_class->construct) - return ConstructTypeNone; + return ConstructType::None; constructData.native.function = constructWithConstructor; - return ConstructTypeHost; + return ConstructType::Host; } bool JSNPObject::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(object); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); if (!thisObject->m_npObject) { - throwInvalidAccessError(exec); + throwInvalidAccessError(exec, scope); return false; } NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); + // If the propertyName is symbol. + if (!npIdentifier) + return false; // Calling NPClass::invoke will call into plug-in code, and there's no telling what the plug-in can do. // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until @@ -289,24 +312,30 @@ bool JSNPObject::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyN return false; } -void JSNPObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot&) +bool JSNPObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot&) { + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); if (!thisObject->m_npObject) { - throwInvalidAccessError(exec); - return; + throwInvalidAccessError(exec, scope); + return false; } NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); + // If the propertyName is symbol. + if (!npIdentifier) + return false; if (!thisObject->m_npObject->_class->hasProperty || !thisObject->m_npObject->_class->hasProperty(thisObject->m_npObject, npIdentifier)) { // FIXME: Should we throw an exception here? - return; + return false; } if (!thisObject->m_npObject->_class->setProperty) - return; + return false; NPVariant variant; thisObject->m_objectMap->convertJSValueToNPVariant(exec, value, variant); @@ -316,9 +345,10 @@ void JSNPObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, J // the call has finished. NPRuntimeObjectMap::PluginProtector protector(thisObject->m_objectMap); + bool result = false; { - JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); - thisObject->m_npObject->_class->setProperty(thisObject->m_npObject, npIdentifier, &variant); + JSLock::DropAllLocks dropAllLocks(commonVM()); + result = thisObject->m_npObject->_class->setProperty(thisObject->m_npObject, npIdentifier, &variant); NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); @@ -326,6 +356,7 @@ void JSNPObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, J } releaseNPVariantValue(&variant); + return result; } bool JSNPObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) @@ -340,9 +371,17 @@ bool JSNPObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned p bool JSNPObject::deleteProperty(ExecState* exec, NPIdentifier propertyName) { - ASSERT_GC_OBJECT_INHERITS(this, info()); + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + ASSERT_THIS_GC_OBJECT_INHERITS(info()); + + // If the propertyName is symbol. + if (!propertyName) + return false; + if (!m_npObject) { - throwInvalidAccessError(exec); + throwInvalidAccessError(exec, scope); return false; } @@ -357,7 +396,7 @@ bool JSNPObject::deleteProperty(ExecState* exec, NPIdentifier propertyName) NPRuntimeObjectMap::PluginProtector protector(m_objectMap); { - JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); + JSLock::DropAllLocks dropAllLocks(commonVM()); // FIXME: Should we throw an exception if removeProperty returns false? if (!m_npObject->_class->removeProperty(m_npObject, propertyName)) @@ -371,10 +410,13 @@ bool JSNPObject::deleteProperty(ExecState* exec, NPIdentifier propertyName) void JSNPObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNameArray, EnumerationMode) { + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + JSNPObject* thisObject = jsCast<JSNPObject*>(object); ASSERT_GC_OBJECT_INHERITS(thisObject, info()); if (!thisObject->m_npObject) { - throwInvalidAccessError(exec); + throwInvalidAccessError(exec, scope); return; } @@ -390,7 +432,7 @@ void JSNPObject::getOwnPropertyNames(JSObject* object, ExecState* exec, Property NPRuntimeObjectMap::PluginProtector protector(thisObject->m_objectMap); { - JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); + JSLock::DropAllLocks dropAllLocks(commonVM()); // FIXME: Should we throw an exception if enumerate returns false? if (!thisObject->m_npObject->_class->enumerate(thisObject->m_npObject, &identifiers, &identifierCount)) @@ -407,7 +449,7 @@ void JSNPObject::getOwnPropertyNames(JSObject* object, ExecState* exec, Property const char* string = identifierRep->string(); int length = strlen(string); - identifier = Identifier(exec, String::fromUTF8WithLatin1Fallback(string, length).impl()); + identifier = Identifier::fromString(exec, String::fromUTF8WithLatin1Fallback(string, length)); } else identifier = Identifier::from(exec, identifierRep->number()); @@ -417,13 +459,16 @@ void JSNPObject::getOwnPropertyNames(JSObject* object, ExecState* exec, Property npnMemFree(identifiers); } -EncodedJSValue JSNPObject::propertyGetter(ExecState* exec, EncodedJSValue slotBase, EncodedJSValue, PropertyName propertyName) +EncodedJSValue JSNPObject::propertyGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName propertyName) { - JSNPObject* thisObj = jsCast<JSNPObject*>(JSValue::decode(slotBase)); + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + JSNPObject* thisObj = jsCast<JSNPObject*>(JSValue::decode(thisValue)); ASSERT_GC_OBJECT_INHERITS(thisObj, info()); if (!thisObj->m_npObject) - return JSValue::encode(throwInvalidAccessError(exec)); + return JSValue::encode(throwInvalidAccessError(exec, scope)); if (!thisObj->m_npObject->_class->getProperty) return JSValue::encode(jsUndefined()); @@ -438,8 +483,12 @@ EncodedJSValue JSNPObject::propertyGetter(ExecState* exec, EncodedJSValue slotBa bool returnValue; { - JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonVM()); + JSLock::DropAllLocks dropAllLocks(commonVM()); NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); + // If the propertyName is symbol. + if (!npIdentifier) + return JSValue::encode(jsUndefined()); + returnValue = thisObj->m_npObject->_class->getProperty(thisObj->m_npObject, npIdentifier, &result); NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); @@ -453,21 +502,28 @@ EncodedJSValue JSNPObject::propertyGetter(ExecState* exec, EncodedJSValue slotBa return JSValue::encode(propertyValue); } -EncodedJSValue JSNPObject::methodGetter(ExecState* exec, EncodedJSValue slotBase, EncodedJSValue, PropertyName propertyName) +EncodedJSValue JSNPObject::methodGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName propertyName) { - JSNPObject* thisObj = jsCast<JSNPObject*>(JSValue::decode(slotBase)); + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + JSNPObject* thisObj = jsCast<JSNPObject*>(JSValue::decode(thisValue)); ASSERT_GC_OBJECT_INHERITS(thisObj, info()); if (!thisObj->m_npObject) - return JSValue::encode(throwInvalidAccessError(exec)); + return JSValue::encode(throwInvalidAccessError(exec, scope)); NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); + // If the propertyName is symbol. + if (!npIdentifier) + return JSValue::encode(throwInvalidAccessError(exec, scope)); + return JSValue::encode(JSNPMethod::create(exec, thisObj->globalObject(), propertyName.publicName(), npIdentifier)); } -JSObject* JSNPObject::throwInvalidAccessError(ExecState* exec) +JSObject* JSNPObject::throwInvalidAccessError(ExecState* exec, ThrowScope& scope) { - return exec->vm().throwException(exec, createReferenceError(exec, "Trying to access object from destroyed plug-in.")); + return throwException(exec, scope, createReferenceError(exec, "Trying to access object from destroyed plug-in.")); } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h index 250d26b0f..b09e90f9b 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h @@ -44,6 +44,7 @@ class NPRuntimeObjectMap; class JSNPObject : public JSC::JSDestructibleObject { public: typedef JSC::JSDestructibleObject Base; + static const unsigned StructureFlags = Base::StructureFlags | JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | JSC::TypeOfShouldCallGetCallData; static JSNPObject* create(JSC::JSGlobalObject* globalObject, NPRuntimeObjectMap* objectMap, NPObject* npObject) { @@ -74,8 +75,6 @@ protected: private: JSNPObject(JSC::JSGlobalObject*, JSC::Structure*, NPRuntimeObjectMap*, NPObject*); - - static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | JSObject::StructureFlags; static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) { @@ -86,7 +85,7 @@ private: static JSC::ConstructType getConstructData(JSC::JSCell*, JSC::ConstructData&); static bool getOwnPropertySlot(JSC::JSObject*, JSC::ExecState*, JSC::PropertyName, JSC::PropertySlot&); - static void put(JSC::JSCell*, JSC::ExecState*, JSC::PropertyName, JSC::JSValue, JSC::PutPropertySlot&); + static bool put(JSC::JSCell*, JSC::ExecState*, JSC::PropertyName, JSC::JSValue, JSC::PutPropertySlot&); static bool deleteProperty(JSC::JSCell*, JSC::ExecState*, JSC::PropertyName); static bool deletePropertyByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName); @@ -95,9 +94,9 @@ private: static void getOwnPropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode); - static JSC::EncodedJSValue propertyGetter(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue, JSC::PropertyName); - static JSC::EncodedJSValue methodGetter(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue, JSC::PropertyName); - static JSC::JSObject* throwInvalidAccessError(JSC::ExecState*); + static JSC::EncodedJSValue propertyGetter(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName); + static JSC::EncodedJSValue methodGetter(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName); + static JSC::JSObject* throwInvalidAccessError(JSC::ExecState*, JSC::ThrowScope&); 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 f33574018..aa75a920d 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp @@ -31,12 +31,11 @@ #include "JSNPObject.h" #include "NPRuntimeObjectMap.h" #include "NPRuntimeUtilities.h" -#include <JavaScriptCore/JSCJSValueInlines.h> +#include <JavaScriptCore/JSCInlines.h> #include <JavaScriptCore/JSCellInlines.h> #include <JavaScriptCore/JSLock.h> #include <JavaScriptCore/JSObject.h> #include <JavaScriptCore/StrongInlines.h> -#include <JavaScriptCore/StructureInlines.h> #include <WebCore/Frame.h> #include <WebCore/IdentifierRep.h> #include <wtf/text/WTFString.h> @@ -49,7 +48,7 @@ namespace WebKit { NPJSObject* NPJSObject::create(VM& vm, NPRuntimeObjectMap* objectMap, JSObject* jsObject) { // We should never have a JSNPObject inside an NPJSObject. - ASSERT(!jsObject->inherits(JSNPObject::info())); + ASSERT(!jsObject->inherits(vm, JSNPObject::info())); NPJSObject* npJSObject = toNPJSObject(createNPObject(0, npClass())); npJSObject->initialize(vm, objectMap, jsObject); @@ -88,7 +87,7 @@ static Identifier identifierFromIdentifierRep(ExecState* exec, IdentifierRep* id const char* string = identifierRep->string(); int length = strlen(string); - return Identifier(exec, String::fromUTF8WithLatin1Fallback(string, length).impl()); + return Identifier::fromString(exec, String::fromUTF8WithLatin1Fallback(string, length)); } bool NPJSObject::hasMethod(NPIdentifier methodName) @@ -102,13 +101,15 @@ bool NPJSObject::hasMethod(NPIdentifier methodName) if (!exec) return false; - JSLockHolder lock(exec); + VM& vm = exec->vm(); + JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); JSValue value = m_jsObject->get(exec, identifierFromIdentifierRep(exec, identifierRep)); - exec->clearException(); + scope.clearException(); CallData callData; - return getCallData(value, callData) != CallTypeNone; + return getCallData(value, callData) != CallType::None; } bool NPJSObject::invoke(NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) @@ -148,7 +149,9 @@ bool NPJSObject::hasProperty(NPIdentifier identifier) if (!exec) return false; - JSLockHolder lock(exec); + VM& vm = exec->vm(); + JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); bool result; if (identifierRep->isString()) @@ -156,7 +159,7 @@ bool NPJSObject::hasProperty(NPIdentifier identifier) else result = m_jsObject->hasProperty(exec, identifierRep->number()); - exec->clearException(); + scope.clearException(); return result; } @@ -168,7 +171,10 @@ bool NPJSObject::getProperty(NPIdentifier propertyName, NPVariant* result) if (!exec) return false; - JSLockHolder lock(exec); + VM& vm = exec->vm(); + JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); + JSValue jsResult; if (identifierRep->isString()) jsResult = m_jsObject->get(exec, identifierFromIdentifierRep(exec, identifierRep)); @@ -176,7 +182,7 @@ bool NPJSObject::getProperty(NPIdentifier propertyName, NPVariant* result) jsResult = m_jsObject->get(exec, identifierRep->number()); m_objectMap->convertJSValueToNPVariant(exec, jsResult, *result); - exec->clearException(); + scope.clearException(); return true; } @@ -188,7 +194,9 @@ bool NPJSObject::setProperty(NPIdentifier propertyName, const NPVariant* value) if (!exec) return false; - JSLockHolder lock(exec); + VM& vm = exec->vm(); + JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); JSValue jsValue = m_objectMap->convertNPVariantToJSValue(exec, m_objectMap->globalObject(), *value); if (identifierRep->isString()) { @@ -196,7 +204,7 @@ bool NPJSObject::setProperty(NPIdentifier propertyName, const NPVariant* value) m_jsObject->methodTable()->put(m_jsObject.get(), exec, identifierFromIdentifierRep(exec, identifierRep), jsValue, slot); } else m_jsObject->methodTable()->putByIndex(m_jsObject.get(), exec, identifierRep->number(), jsValue, false); - exec->clearException(); + scope.clearException(); return true; } @@ -209,26 +217,29 @@ bool NPJSObject::removeProperty(NPIdentifier propertyName) if (!exec) return false; - JSLockHolder lock(exec); + VM& vm = exec->vm(); + JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); + if (identifierRep->isString()) { Identifier identifier = identifierFromIdentifierRep(exec, identifierRep); if (!m_jsObject->hasProperty(exec, identifier)) { - exec->clearException(); + scope.clearException(); return false; } m_jsObject->methodTable()->deleteProperty(m_jsObject.get(), exec, identifier); } else { if (!m_jsObject->hasProperty(exec, identifierRep->number())) { - exec->clearException(); + scope.clearException(); return false; } m_jsObject->methodTable()->deletePropertyByIndex(m_jsObject.get(), exec, identifierRep->number()); } - exec->clearException(); + scope.clearException(); return true; } @@ -240,8 +251,8 @@ bool NPJSObject::enumerate(NPIdentifier** identifiers, uint32_t* identifierCount JSLockHolder lock(exec); - PropertyNameArray propertyNames(exec); - m_jsObject->methodTable()->getPropertyNames(m_jsObject.get(), exec, propertyNames, ExcludeDontEnumProperties); + PropertyNameArray propertyNames(exec, PropertyNameMode::Strings); + m_jsObject->methodTable()->getPropertyNames(m_jsObject.get(), exec, propertyNames, EnumerationMode()); NPIdentifier* nameIdentifiers = npnMemNewArray<NPIdentifier>(propertyNames.size()); @@ -260,11 +271,13 @@ bool NPJSObject::construct(const NPVariant* arguments, uint32_t argumentCount, N if (!exec) return false; - JSLockHolder lock(exec); + VM& vm = exec->vm(); + JSLockHolder lock(vm); + auto scope = DECLARE_CATCH_SCOPE(vm); ConstructData constructData; ConstructType constructType = getConstructData(m_jsObject.get(), constructData); - if (constructType == ConstructTypeNone) + if (constructType == ConstructType::None) return false; // Convert the passed in arguments. @@ -276,16 +289,19 @@ bool NPJSObject::construct(const NPVariant* arguments, uint32_t argumentCount, N // Convert and return the new object. m_objectMap->convertJSValueToNPVariant(exec, value, *result); - exec->clearException(); + scope.clearException(); return true; } bool NPJSObject::invoke(ExecState* exec, JSGlobalObject* globalObject, JSValue function, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result) { + VM& vm = exec->vm(); + auto scope = DECLARE_CATCH_SCOPE(vm); + CallData callData; CallType callType = getCallData(function, callData); - if (callType == CallTypeNone) + if (callType == CallType::None) return false; // Convert the passed in arguments. @@ -295,9 +311,18 @@ bool NPJSObject::invoke(ExecState* exec, JSGlobalObject* globalObject, JSValue f JSValue value = JSC::call(exec, function, callType, callData, m_jsObject.get(), argumentList); + if (UNLIKELY(scope.exception())) { + scope.clearException(); + return false; + } + // Convert and return the result of the function call. m_objectMap->convertJSValueToNPVariant(exec, value, *result); - exec->clearException(); + + if (UNLIKELY(scope.exception())) { + scope.clearException(); + return false; + } return true; } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp index 8b16ca528..2db8bb446 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -41,8 +41,6 @@ #include <JavaScriptCore/StrongInlines.h> #include <WebCore/DOMWrapperWorld.h> #include <WebCore/Frame.h> -#include <WebCore/Page.h> -#include <WebCore/PageThrottler.h> #include <WebCore/ScriptController.h> #include <wtf/NeverDestroyed.h> @@ -72,7 +70,7 @@ NPRuntimeObjectMap::PluginProtector::~PluginProtector() NPObject* NPRuntimeObjectMap::getOrCreateNPObject(VM& vm, JSObject* jsObject) { // If this is a JSNPObject, we can just get its underlying NPObject. - if (jsObject->classInfo() == JSNPObject::info()) { + if (jsObject->classInfo(vm) == JSNPObject::info()) { JSNPObject* jsNPObject = jsCast<JSNPObject*>(jsObject); NPObject* npObject = jsNPObject->npObject(); @@ -189,17 +187,12 @@ bool NPRuntimeObjectMap::evaluate(NPObject* npObject, const String& scriptString if (!globalObject) return false; - if (m_pluginView && !m_pluginView->isBeingDestroyed()) { - if (Page* page = m_pluginView->frame()->page()) - page->pageThrottler().reportInterestingEvent(); - } - ExecState* exec = globalObject->globalExec(); JSLockHolder lock(exec); JSValue thisValue = getOrCreateJSObject(globalObject.get(), npObject); - JSValue resultValue = JSC::evaluate(exec, makeSource(scriptString), thisValue); + JSValue resultValue = JSC::evaluate(exec, makeSource(scriptString, { }), thisValue); convertJSValueToNPVariant(exec, resultValue, *result); return true; @@ -270,12 +263,15 @@ void NPRuntimeObjectMap::setGlobalException(const String& exceptionString) void NPRuntimeObjectMap::moveGlobalExceptionToExecState(ExecState* exec) { + VM& vm = exec->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + if (globalExceptionString().isNull()) return; { - JSLockHolder lock(exec); - exec->vm().throwException(exec, createError(exec, globalExceptionString())); + JSLockHolder lock(vm); + throwException(exec, scope, createError(exec, globalExceptionString())); } globalExceptionString() = String(); @@ -303,7 +299,7 @@ void NPRuntimeObjectMap::addToInvalidationQueue(NPObject* npObject) void NPRuntimeObjectMap::finalize(JSC::Handle<JSC::Unknown> handle, void* context) { - JSNPObject* object = jsCast<JSNPObject*>(handle.get().asCell()); + JSNPObject* object = static_cast<JSNPObject*>(handle.get().asCell()); weakRemove(m_jsNPObjects, static_cast<NPObject*>(context), object); addToInvalidationQueue(object->leakNPObject()); } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h index fade41df5..85509ab49 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.h @@ -90,7 +90,7 @@ public: private: // WeakHandleOwner - virtual void finalize(JSC::Handle<JSC::Unknown>, void* context); + void finalize(JSC::Handle<JSC::Unknown>, void* context) override; void addToInvalidationQueue(NPObject*); void invalidateQueuedObjects(); diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp index f1f3d1878..00bd6cd83 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.cpp @@ -32,13 +32,23 @@ #include "NetscapePlugin.h" #include "PluginController.h" #include <WebCore/HTTPHeaderMap.h> +#include <WebCore/HTTPHeaderNames.h> #include <WebCore/IdentifierRep.h> #include <WebCore/NotImplemented.h> #include <WebCore/ProtectionSpace.h> #include <WebCore/SharedBuffer.h> +#include <memory> #include <utility> #include <wtf/text/StringBuilder.h> +#if PLATFORM(COCOA) +#include <WebCore/MachSendRight.h> +#endif + +#if PLUGIN_ARCHITECTURE(X11) +#include <WebCore/PlatformDisplayX11.h> +#endif + using namespace WebCore; namespace WebKit { @@ -49,11 +59,11 @@ public: explicit PluginDestructionProtector(NetscapePlugin* plugin) { if (plugin) - m_protector = adoptPtr(new PluginController::PluginDestructionProtector(static_cast<Plugin*>(plugin)->controller())); + m_protector = std::make_unique<PluginController::PluginDestructionProtector>(static_cast<Plugin*>(plugin)->controller()); } private: - OwnPtr<PluginController::PluginDestructionProtector> m_protector; + std::unique_ptr<PluginController::PluginDestructionProtector> m_protector; }; static bool startsWithBlankLine(const char* bytes, unsigned length) @@ -121,25 +131,13 @@ static String capitalizeRFC822HeaderFieldName(const String& name) { bool capitalizeCharacter = true; StringBuilder result; - for (unsigned i = 0; i < name.length(); i++) { - UChar c; - - if (capitalizeCharacter && name[i] >= 'a' && name[i] <= 'z') - c = toASCIIUpper(name[i]); - else if (!capitalizeCharacter && name[i] >= 'A' && name[i] <= 'Z') - c = toASCIILower(name[i]); - else - c = name[i]; - + result.append(capitalizeCharacter ? toASCIIUpper(name[i]) : toASCIILower(name[i])); if (name[i] == '-') capitalizeCharacter = true; else capitalizeCharacter = false; - - result.append(c); } - return result.toString(); } @@ -195,7 +193,7 @@ static HTTPHeaderMap parseRFC822HeaderFields(const char* bytes, unsigned length) break; } if (colon == endOfLine) - value = ""; + value = emptyString(); else value = String(colon, endOfLine - colon); @@ -244,15 +242,14 @@ static NPError parsePostBuffer(bool isFile, const char *buffer, uint32_t length, // Sometimes plugins like to set Content-Length themselves when they post, // but WebFoundation does not like that. So we will remove the header // and instead truncate the data to the requested length. - String contentLength = headerFields.get("Content-Length"); + String contentLength = headerFields.get(HTTPHeaderName::ContentLength); if (!contentLength.isNull()) dataLength = std::min(contentLength.toInt(), (int)dataLength); - headerFields.remove("Content-Length"); + headerFields.remove(HTTPHeaderName::ContentLength); postBuffer += location; postBufferSize = dataLength; - } } } @@ -298,7 +295,7 @@ static NPError NPN_PostURL(NPP npp, const char* url, const char* target, uint32_ return error; RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); - plugin->loadURL("POST", makeURLString(url), target, headerFields, postData, false, 0); + plugin->loadURL("POST", makeURLString(url), target, WTFMove(headerFields), postData, false, 0); return NPERR_NO_ERROR; } @@ -331,7 +328,7 @@ static void NPN_Status(NPP npp, const char* message) { String statusbarText; if (!message) - statusbarText = ""; + statusbarText = emptyString(); else statusbarText = String::fromUTF8WithLatin1Fallback(message, strlen(message)); @@ -400,7 +397,7 @@ static NPError NPN_PostURLNotify(NPP npp, const char* url, const char* target, u return NPERR_NO_ERROR; } -#if PLATFORM(MAC) +#if PLATFORM(COCOA) // Whether the browser supports compositing of Core Animation plug-ins. static const unsigned WKNVSupportsCompositingCoreAnimationPluginsBool = 74656; @@ -409,8 +406,6 @@ static const unsigned WKNVExpectsNonretainedLayer = 74657; // 74658 and 74659 are no longer implemented. -static const unsigned WKNVPlugInContainer = 74660; - #endif static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) @@ -441,7 +436,13 @@ static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) *(NPBool*)value = plugin->isPrivateBrowsingEnabled(); break; } -#if PLATFORM(MAC) + + case NPNVmuteAudioBool: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + *(NPBool*)value = plugin->isMuted(); + break; + } +#if PLATFORM(COCOA) case NPNVsupportsCoreGraphicsBool: // Always claim to support the Core Graphics drawing model. *(NPBool*)value = true; @@ -482,7 +483,7 @@ static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) case WKNVCALayerRenderServerPort: { RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); - *(mach_port_t*)value = plugin->compositingRenderServerPort(); + *(mach_port_t*)value = plugin->compositingRenderServerPort().sendRight(); break; } @@ -495,12 +496,6 @@ static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) break; } - case WKNVPlugInContainer: { - RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); - *reinterpret_cast<void**>(value) = plugin->plugInContainer(); - break; - } - #ifndef NP_NO_QUICKDRAW case NPNVsupportsQuickDrawBool: // We don't support the QuickDraw drawing model. @@ -513,18 +508,21 @@ static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) break; #endif #elif PLUGIN_ARCHITECTURE(X11) - case NPNVxDisplay: { - if (!npp) - return NPERR_GENERIC_ERROR; - *reinterpret_cast<Display**>(value) = NetscapePlugin::x11HostDisplay(); - break; - } - case NPNVSupportsXEmbedBool: - *static_cast<NPBool*>(value) = true; - break; - case NPNVSupportsWindowless: - *static_cast<NPBool*>(value) = true; - break; + case NPNVxDisplay: { + if (!npp) + return NPERR_GENERIC_ERROR; + auto& display = PlatformDisplay::sharedDisplay(); + if (display.type() != PlatformDisplay::Type::X11) + return NPERR_GENERIC_ERROR; + *reinterpret_cast<Display**>(value) = downcast<PlatformDisplayX11>(display).native(); + break; + } + case NPNVSupportsXEmbedBool: + *static_cast<NPBool*>(value) = PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11; + break; + case NPNVSupportsWindowless: + *static_cast<NPBool*>(value) = true; + break; case NPNVToolkit: { // Gtk based plugins need to be assured about the toolkit version. @@ -546,7 +544,7 @@ static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) static NPError NPN_SetValue(NPP npp, NPPVariable variable, void *value) { switch (variable) { -#if PLATFORM(MAC) +#if PLATFORM(COCOA) case NPPVpluginDrawingModel: { RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); @@ -574,6 +572,12 @@ static NPError NPN_SetValue(NPP npp, NPPVariable variable, void *value) return NPERR_NO_ERROR; } + case NPPVpluginIsPlayingAudio: { + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + plugin->setIsPlayingAudio(value); + return NPERR_NO_ERROR; + } + default: notImplemented(); return NPERR_GENERIC_ERROR; @@ -940,7 +944,7 @@ static void NPN_UnscheduleTimer(NPP npp, uint32_t timerID) plugin->unscheduleTimer(timerID); } -#if PLATFORM(MAC) +#if PLATFORM(COCOA) static NPError NPN_PopUpContextMenu(NPP npp, NPMenu* menu) { RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); @@ -966,6 +970,13 @@ static NPBool NPN_ConvertPoint(NPP npp, double sourceX, double sourceY, NPCoordi } #endif +static void NPN_URLRedirectResponse(NPP npp, void* notifyData, NPBool allow) +{ + RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); + + plugin->urlRedirectResponse(notifyData, allow); +} + static void initializeBrowserFuncs(NPNetscapeFuncs &netscapeFuncs) { netscapeFuncs.size = sizeof(NPNetscapeFuncs); @@ -1022,13 +1033,14 @@ static void initializeBrowserFuncs(NPNetscapeFuncs &netscapeFuncs) netscapeFuncs.getauthenticationinfo = NPN_GetAuthenticationInfo; netscapeFuncs.scheduletimer = NPN_ScheduleTimer; netscapeFuncs.unscheduletimer = NPN_UnscheduleTimer; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) netscapeFuncs.popupcontextmenu = NPN_PopUpContextMenu; netscapeFuncs.convertpoint = NPN_ConvertPoint; #else netscapeFuncs.popupcontextmenu = 0; netscapeFuncs.convertpoint = 0; #endif + netscapeFuncs.urlredirectresponse = NPN_URLRedirectResponse; } NPNetscapeFuncs* netscapeBrowserFuncs() diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.h index 37e61daa3..07d421fb3 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapeBrowserFuncs.h @@ -32,8 +32,10 @@ namespace WebKit { +#if PLUGIN_ARCHITECTURE(MAC) // The Core Animation render server port. static const unsigned WKNVCALayerRenderServerPort = 71879; +#endif NPNetscapeFuncs* netscapeBrowserFuncs(); diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp index 5d894e754..5c9a91824 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp @@ -42,6 +42,10 @@ #include <utility> #include <wtf/text/CString.h> +#if PLUGIN_ARCHITECTURE(X11) +#include "NetscapePluginUnix.h" +#endif + using namespace WebCore; namespace WebKit { @@ -49,20 +53,21 @@ namespace WebKit { // The plug-in that we're currently calling NPP_New for. static NetscapePlugin* currentNPPNewPlugin; -PassRefPtr<NetscapePlugin> NetscapePlugin::create(PassRefPtr<NetscapePluginModule> pluginModule) +RefPtr<NetscapePlugin> NetscapePlugin::create(PassRefPtr<NetscapePluginModule> pluginModule) { if (!pluginModule) - return 0; + return nullptr; - return adoptRef(new NetscapePlugin(pluginModule)); + return adoptRef(*new NetscapePlugin(pluginModule)); } NetscapePlugin::NetscapePlugin(PassRefPtr<NetscapePluginModule> pluginModule) - : m_nextRequestID(0) + : Plugin(NetscapePluginType) + , m_nextRequestID(0) , m_pluginModule(pluginModule) , m_npWindow() , m_isStarted(false) -#if PLATFORM(MAC) +#if PLATFORM(COCOA) , m_isWindowed(false) #else , m_isWindowed(true) @@ -73,11 +78,11 @@ NetscapePlugin::NetscapePlugin(PassRefPtr<NetscapePluginModule> pluginModule) , m_hasCalledSetWindow(false) , m_isVisible(false) , m_nextTimerID(0) -#if PLATFORM(MAC) +#if PLATFORM(COCOA) , m_drawingModel(static_cast<NPDrawingModel>(-1)) , m_eventModel(static_cast<NPEventModel>(-1)) , m_pluginReturnsNonretainedLayer(!m_pluginModule->pluginQuirks().contains(PluginQuirks::ReturnsRetainedCoreAnimationLayer)) - , m_layerHostingMode(LayerHostingModeDefault) + , m_layerHostingMode(LayerHostingMode::InProcess) , m_currentMouseEvent(0) , m_pluginHasFocus(false) , m_windowHasFocus(false) @@ -89,12 +94,6 @@ NetscapePlugin::NetscapePlugin(PassRefPtr<NetscapePluginModule> pluginModule) , m_nullEventTimer(RunLoop::main(), this, &NetscapePlugin::nullEventTimerFired) , m_npCGContext() #endif -#elif PLUGIN_ARCHITECTURE(X11) - , m_drawable(0) - , m_pluginDisplay(0) -#if PLATFORM(GTK) - , m_platformPluginWidget(0) -#endif #endif { m_npp.ndata = this; @@ -111,10 +110,10 @@ NetscapePlugin::~NetscapePlugin() m_pluginModule->decrementLoadCount(); } -PassRefPtr<NetscapePlugin> NetscapePlugin::fromNPP(NPP npp) +RefPtr<NetscapePlugin> NetscapePlugin::fromNPP(NPP npp) { if (!npp) - return 0; + return nullptr; return static_cast<NetscapePlugin*>(npp->ndata); } @@ -147,13 +146,6 @@ const char* NetscapePlugin::userAgent(NPP npp) const char* NetscapePlugin::userAgent() { -#if PLUGIN_ARCHITECTURE(WIN) - static const char* MozillaUserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0"; - - if (quirks().contains(PluginQuirks::WantsMozillaUserAgent)) - return MozillaUserAgent; -#endif - if (m_userAgent.isNull()) { String userAgent = controller()->userAgent(); ASSERT(!userAgent.isNull()); @@ -177,10 +169,10 @@ void NetscapePlugin::loadURL(const String& method, const String& urlString, cons if (target.isNull()) { // The browser is going to send the data in a stream, create a plug-in stream. - RefPtr<NetscapePluginStream> pluginStream = NetscapePluginStream::create(this, requestID, urlString, sendNotification, notificationData); + auto pluginStream = NetscapePluginStream::create(this, requestID, urlString, sendNotification, notificationData); ASSERT(!m_streams.contains(requestID)); - m_streams.set(requestID, pluginStream.release()); + m_streams.set(requestID, WTFMove(pluginStream)); return; } @@ -254,6 +246,11 @@ bool NetscapePlugin::isPrivateBrowsingEnabled() return controller()->isPrivateBrowsingEnabled(); } +bool NetscapePlugin::isMuted() const +{ + return controller()->isMuted(); +} + NPObject* NetscapePlugin::windowScriptNPObject() { return controller()->windowScriptNPObject(); @@ -278,7 +275,7 @@ void NetscapePlugin::cancelStreamLoad(NetscapePluginStream* pluginStream) void NetscapePlugin::removePluginStream(NetscapePluginStream* pluginStream) { if (pluginStream == m_manualStream) { - m_manualStream = 0; + m_manualStream = nullptr; return; } @@ -288,11 +285,7 @@ void NetscapePlugin::removePluginStream(NetscapePluginStream* pluginStream) bool NetscapePlugin::isAcceleratedCompositingEnabled() { -#if USE(ACCELERATED_COMPOSITING) return controller()->isAcceleratedCompositingEnabled(); -#else - return false; -#endif } void NetscapePlugin::pushPopupsEnabledState(bool state) @@ -309,15 +302,12 @@ void NetscapePlugin::popPopupsEnabledState() void NetscapePlugin::pluginThreadAsyncCall(void (*function)(void*), void* userData) { - RunLoop::main()->dispatch(WTF::bind(&NetscapePlugin::handlePluginThreadAsyncCall, this, function, userData)); -} - -void NetscapePlugin::handlePluginThreadAsyncCall(void (*function)(void*), void* userData) -{ - if (!m_isStarted) - return; + RunLoop::main().dispatch([protectedThis = makeRef(*this), function, userData] { + if (!protectedThis->m_isStarted) + return; - function(userData); + function(userData); + }); } NetscapePlugin::Timer::Timer(NetscapePlugin* netscapePlugin, unsigned timerID, unsigned interval, bool repeat, TimerFunc timerFunc) @@ -369,7 +359,7 @@ uint32_t NetscapePlugin::scheduleTimer(unsigned interval, bool repeat, void (*ti // FIXME: Based on the plug-in visibility, figure out if we should throttle the timer, or if we should start it at all. timer->start(); - m_timers.set(timerID, std::move(timer)); + m_timers.set(timerID, WTFMove(timer)); return timerID; } @@ -403,7 +393,41 @@ void NetscapePlugin::setCookiesForURL(const String& urlString, const String& coo bool NetscapePlugin::getAuthenticationInfo(const ProtectionSpace& protectionSpace, String& username, String& password) { return controller()->getAuthenticationInfo(protectionSpace, username, password); -} +} + +void NetscapePlugin::registerRedirect(NetscapePluginStream* stream, const URL& requestURL, int redirectResponseStatus, void* notificationData) +{ + // NPP_URLRedirectNotify may synchronously request this stream back out, so set it first + m_redirects.set(notificationData, std::make_pair(stream, requestURL.string())); + if (!NPP_URLRedirectNotify(requestURL.string().utf8().data(), redirectResponseStatus, notificationData)) { + m_redirects.take(notificationData); + controller()->continueStreamLoad(stream->streamID()); + } +} + +void NetscapePlugin::urlRedirectResponse(void* notifyData, bool allow) +{ + if (!m_redirects.contains(notifyData)) + return; + + auto redirect = m_redirects.take(notifyData); + if (!redirect.first) + return; + + RefPtr<NetscapePluginStream> stream = redirect.first; + if (!allow) { + controller()->cancelStreamLoad(stream->streamID()); + stream->stop(NPRES_USER_BREAK); + } else { + stream->setURL(redirect.second); + controller()->continueStreamLoad(stream->streamID()); + } +} + +void NetscapePlugin::setIsPlayingAudio(bool isPlayingAudio) +{ + controller()->setPluginIsPlayingAudio(isPlayingAudio); +} NPError NetscapePlugin::NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* savedData) { @@ -455,6 +479,15 @@ void NetscapePlugin::NPP_URLNotify(const char* url, NPReason reason, void* notif m_pluginModule->pluginFuncs().urlnotify(&m_npp, url, reason, notifyData); } +bool NetscapePlugin::NPP_URLRedirectNotify(const char* url, int32_t status, void* notifyData) +{ + if (!m_pluginModule->pluginFuncs().urlredirectnotify) + return false; + + m_pluginModule->pluginFuncs().urlredirectnotify(&m_npp, url, status, notifyData); + return true; +} + NPError NetscapePlugin::NPP_GetValue(NPPVariable variable, void *value) { if (!m_pluginModule->pluginFuncs().getvalue) @@ -572,7 +605,7 @@ static bool isTransparentSilverlightBackgroundValue(const String& lowercaseBackg } } else if (lowercaseBackgroundValue.startsWith("sc#")) { Vector<String> components; - lowercaseBackgroundValue.substring(3).split(",", components); + lowercaseBackgroundValue.substring(3).split(',', components); // An ScRGB value with alpha transparency, in the form sc#A,R,G,B. if (components.size() == 4) { @@ -604,13 +637,31 @@ bool NetscapePlugin::initialize(const Parameters& parameters) #if PLUGIN_ARCHITECTURE(MAC) if (m_pluginModule->pluginQuirks().contains(PluginQuirks::WantsLowercaseParameterNames)) - parameterName = parameterName.lower(); + parameterName = parameterName.convertToASCIILowercase(); #endif paramNames.append(parameterName.utf8()); paramValues.append(parameters.values[i].utf8()); } +#if PLUGIN_ARCHITECTURE(X11) + if (equalLettersIgnoringASCIICase(parameters.mimeType, "application/x-shockwave-flash")) { + size_t wmodeIndex = parameters.names.find("wmode"); + if (wmodeIndex != notFound) { + // Transparent window mode is not supported by X11 backend. + if (equalLettersIgnoringASCIICase(parameters.values[wmodeIndex], "transparent") + || (m_pluginModule->pluginQuirks().contains(PluginQuirks::ForceFlashWindowlessMode) && equalLettersIgnoringASCIICase(parameters.values[wmodeIndex], "window"))) + paramValues[wmodeIndex] = "opaque"; + } else if (m_pluginModule->pluginQuirks().contains(PluginQuirks::ForceFlashWindowlessMode)) { + paramNames.append("wmode"); + paramValues.append("opaque"); + } + } else if (equalLettersIgnoringASCIICase(parameters.mimeType, "application/x-webkit-test-netscape")) { + paramNames.append("windowedPlugin"); + paramValues.append("false"); + } +#endif + // The strings that these pointers point to are kept alive by paramNames and paramValues. Vector<const char*> names; Vector<const char*> values; @@ -622,8 +673,8 @@ bool NetscapePlugin::initialize(const Parameters& parameters) #if PLUGIN_ARCHITECTURE(MAC) if (m_pluginModule->pluginQuirks().contains(PluginQuirks::MakeOpaqueUnlessTransparentSilverlightBackgroundAttributeExists)) { for (size_t i = 0; i < parameters.names.size(); ++i) { - if (equalIgnoringCase(parameters.names[i], "background")) { - setIsTransparent(isTransparentSilverlightBackgroundValue(parameters.values[i].lower())); + if (equalLettersIgnoringASCIICase(parameters.names[i], "background")) { + setIsTransparent(isTransparentSilverlightBackgroundValue(parameters.values[i].convertToASCIILowercase())); break; } } @@ -686,17 +737,17 @@ void NetscapePlugin::destroy() m_timers.clear(); } -void NetscapePlugin::paint(GraphicsContext* context, const IntRect& dirtyRect) +void NetscapePlugin::paint(GraphicsContext& context, const IntRect& dirtyRect) { ASSERT(m_isStarted); platformPaint(context, dirtyRect); } -PassRefPtr<ShareableBitmap> NetscapePlugin::snapshot() +RefPtr<ShareableBitmap> NetscapePlugin::snapshot() { if (!supportsSnapshotting() || m_pluginSize.isEmpty()) - return 0; + return nullptr; ASSERT(m_isStarted); @@ -708,11 +759,11 @@ PassRefPtr<ShareableBitmap> NetscapePlugin::snapshot() // FIXME: We should really call applyDeviceScaleFactor instead of scale, but that ends up calling into WKSI // which we currently don't have initiated in the plug-in process. - context->scale(FloatSize(contentsScaleFactor(), contentsScaleFactor())); + context->scale(contentsScaleFactor()); - platformPaint(context.get(), IntRect(IntPoint(), m_pluginSize), true); + platformPaint(*context, IntRect(IntPoint(), m_pluginSize), true); - return bitmap.release(); + return bitmap; } bool NetscapePlugin::isTransparent() @@ -744,8 +795,10 @@ void NetscapePlugin::geometryDidChange(const IntSize& pluginSize, const IntRect& m_clipRect = clipRect; m_pluginToRootViewTransform = pluginToRootViewTransform; +#if PLUGIN_ARCHITECTURE(X11) IntPoint frameRectLocationInWindowCoordinates = m_pluginToRootViewTransform.mapPoint(IntPoint()); m_frameRectInWindowCoordinates = IntRect(frameRectLocationInWindowCoordinates, m_pluginSize); +#endif platformGeometryDidChange(); @@ -796,6 +849,14 @@ void NetscapePlugin::didEvaluateJavaScript(uint64_t requestID, const String& res pluginStream->sendJavaScriptStream(result); } +void NetscapePlugin::streamWillSendRequest(uint64_t streamID, const URL& requestURL, const URL& redirectResponseURL, int redirectResponseStatus) +{ + ASSERT(m_isStarted); + + if (NetscapePluginStream* pluginStream = streamFromID(streamID)) + pluginStream->willSendRequest(requestURL, redirectResponseURL, redirectResponseStatus); +} + void NetscapePlugin::streamDidReceiveResponse(uint64_t streamID, const URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& /* suggestedFileName */) { @@ -929,7 +990,7 @@ bool NetscapePlugin::shouldAllowNavigationFromDrags() return false; } -bool NetscapePlugin::handlesPageScaleFactor() +bool NetscapePlugin::handlesPageScaleFactor() const { return false; } @@ -1040,15 +1101,15 @@ Scrollbar* NetscapePlugin::verticalScrollbar() bool NetscapePlugin::supportsSnapshotting() const { -#if PLATFORM(MAC) +#if PLATFORM(COCOA) return m_pluginModule && m_pluginModule->pluginQuirks().contains(PluginQuirks::SupportsSnapshotting); #endif return false; } -PassRefPtr<WebCore::SharedBuffer> NetscapePlugin::liveResourceData() const +RefPtr<WebCore::SharedBuffer> NetscapePlugin::liveResourceData() const { - return 0; + return nullptr; } IntPoint NetscapePlugin::convertToRootView(const IntPoint& pointInPluginCoordinates) const @@ -1058,13 +1119,31 @@ IntPoint NetscapePlugin::convertToRootView(const IntPoint& pointInPluginCoordina bool NetscapePlugin::convertFromRootView(const IntPoint& pointInRootViewCoordinates, IntPoint& pointInPluginCoordinates) { - if (!m_pluginToRootViewTransform.isInvertible()) - return false; + if (auto inverse = m_pluginToRootViewTransform.inverse()) { + pointInPluginCoordinates = inverse.value().mapPoint(pointInRootViewCoordinates); + return true; + } + return false; +} - pointInPluginCoordinates = m_pluginToRootViewTransform.inverse().mapPoint(pointInRootViewCoordinates); - return true; +void NetscapePlugin::mutedStateChanged(bool muted) +{ + NPBool value = muted; + NPP_SetValue(NPNVmuteAudioBool, &value); } +#if !PLATFORM(COCOA) + +void NetscapePlugin::windowFocusChanged(bool) +{ +} + +void NetscapePlugin::windowVisibilityChanged(bool) +{ +} + +#endif + } // namespace WebKit #endif // ENABLE(NETSCAPE_PLUGIN_API) diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h index 06d4c8ce2..bf569fe29 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,28 +39,28 @@ #include <wtf/text/StringHash.h> namespace WebCore { - class HTTPHeaderMap; - class ProtectionSpace; - class SharedBuffer; +class MachSendRight; +class HTTPHeaderMap; +class ProtectionSpace; +class SharedBuffer; } -OBJC_CLASS WKNPAPIPlugInContainer; - namespace WebKit { class NetscapePluginStream; - +class NetscapePluginUnix; + class NetscapePlugin : public Plugin { public: - static PassRefPtr<NetscapePlugin> create(PassRefPtr<NetscapePluginModule> pluginModule); + static RefPtr<NetscapePlugin> create(PassRefPtr<NetscapePluginModule>); virtual ~NetscapePlugin(); - static PassRefPtr<NetscapePlugin> fromNPP(NPP); + static RefPtr<NetscapePlugin> fromNPP(NPP); // In-process NetscapePlugins don't support asynchronous initialization. - virtual bool isBeingAsynchronouslyInitialized() const { return false; } + bool isBeingAsynchronouslyInitialized() const override { return false; } -#if PLATFORM(MAC) +#if PLATFORM(COCOA) NPError setDrawingModel(NPDrawingModel); NPError setEventModel(NPEventModel); NPBool convertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double& destX, double& destY, NPCoordinateSpace destSpace); @@ -71,14 +71,11 @@ public: bool hasHandledAKeyDownEvent() const { return m_hasHandledAKeyDownEvent; } - mach_port_t compositingRenderServerPort(); - void openPluginPreferencePane(); + const WebCore::MachSendRight& compositingRenderServerPort(); // Computes an affine transform from the given coordinate space to the screen coordinate space. bool getScreenTransform(NPCoordinateSpace sourceSpace, WebCore::AffineTransform&); - WKNPAPIPlugInContainer* plugInContainer(); - #ifndef NP_NO_CARBON WindowRef windowRef() const; bool isWindowActive() const { return m_windowHasFocus; } @@ -90,6 +87,12 @@ public: #endif +#if PLUGIN_ARCHITECTURE(X11) + const WebCore::IntRect& frameRectInWindowCoordinates() const { return m_frameRectInWindowCoordinates; } +#endif + const WebCore::IntRect& clipRect() const { return m_clipRect; } + const WebCore::IntSize& size() const { return m_pluginSize; } + PluginQuirks quirks() const { return m_pluginModule->pluginQuirks(); } void invalidate(const NPRect*); @@ -103,6 +106,9 @@ public: static void setException(const String&); bool evaluate(NPObject*, const String&scriptString, NPVariant* result); bool isPrivateBrowsingEnabled(); + bool isMuted() const; + bool isWindowed() const { return m_isWindowed; } + bool isVisible() const { return m_isVisible; } static void setSetExceptionFunction(void (*)(const String&)); @@ -120,9 +126,6 @@ public: void pluginThreadAsyncCall(void (*function)(void*), void* userData); - // Called on the plug-in run loop (which is currently the main thread run loop). - void handlePluginThreadAsyncCall(void (*function)(void*), void* userData); - unsigned scheduleTimer(unsigned interval, bool repeat, void (*timerFunc)(NPP, unsigned timerID)); void unscheduleTimer(unsigned timerID); @@ -132,6 +135,11 @@ public: void setCookiesForURL(const String& urlString, const String& cookieString); bool getAuthenticationInfo(const WebCore::ProtectionSpace&, String& username, String& password); + void setIsPlayingAudio(bool); + + void registerRedirect(NetscapePluginStream*, const WebCore::URL& requestURL, int redirectResponseStatus, void* notificationData); + void urlRedirectResponse(void* notifyData, bool allow); + // Member functions for calling into the plug-in. NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData*); NPError NPP_Destroy(NPSavedData**); @@ -143,9 +151,13 @@ public: int32_t NPP_Write(NPStream*, int32_t offset, int32_t len, void* buffer); int16_t NPP_HandleEvent(void* event); void NPP_URLNotify(const char* url, NPReason, void* notifyData); + bool NPP_URLRedirectNotify(const char* url, int32_t status, void* notifyData); NPError NPP_GetValue(NPPVariable, void *value); NPError NPP_SetValue(NPNVariable, void *value); + // Convert the given point from plug-in coordinates to root view coordinates. + WebCore::IntPoint convertToRootView(const WebCore::IntPoint&) const override; + private: NetscapePlugin(PassRefPtr<NetscapePluginModule> pluginModule); @@ -164,7 +176,7 @@ private: bool platformInvalidate(const WebCore::IntRect&); void platformGeometryDidChange(); void platformVisibilityDidChange(); - void platformPaint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect, bool isSnapshot = false); + void platformPaint(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect, bool isSnapshot = false); bool platformHandleMouseEvent(const WebMouseEvent&); bool platformHandleWheelEvent(const WebWheelEvent&); @@ -176,60 +188,62 @@ private: static bool wantsPluginRelativeNPWindowCoordinates(); // Plugin - virtual bool initialize(const Parameters&); - virtual void destroy(); - virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect); - virtual PassRefPtr<ShareableBitmap> snapshot(); -#if PLATFORM(MAC) - virtual PlatformLayer* pluginLayer(); + bool initialize(const Parameters&) override; + void destroy() override; + void paint(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect) override; + RefPtr<ShareableBitmap> snapshot() override; +#if PLATFORM(COCOA) + PlatformLayer* pluginLayer() override; #endif - virtual bool isTransparent(); - virtual bool wantsWheelEvents() override; - virtual void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform); - virtual void visibilityDidChange(bool isVisible); - virtual void frameDidFinishLoading(uint64_t requestID); - virtual void frameDidFail(uint64_t requestID, bool wasCancelled); - virtual void didEvaluateJavaScript(uint64_t requestID, const String& result); - virtual void streamDidReceiveResponse(uint64_t streamID, const WebCore::URL& responseURL, uint32_t streamLength, - uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName); - virtual void streamDidReceiveData(uint64_t streamID, const char* bytes, int length); - virtual void streamDidFinishLoading(uint64_t streamID); - virtual void streamDidFail(uint64_t streamID, bool wasCancelled); - virtual void manualStreamDidReceiveResponse(const WebCore::URL& responseURL, uint32_t streamLength, - uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName); - virtual void manualStreamDidReceiveData(const char* bytes, int length); - virtual void manualStreamDidFinishLoading(); - virtual void manualStreamDidFail(bool wasCancelled); + bool isTransparent() override; + bool wantsWheelEvents() override; + void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform) override; + void visibilityDidChange(bool isVisible) override; + void frameDidFinishLoading(uint64_t requestID) override; + void frameDidFail(uint64_t requestID, bool wasCancelled) override; + void didEvaluateJavaScript(uint64_t requestID, const String& result) override; + void streamWillSendRequest(uint64_t streamID, const WebCore::URL& requestURL, const WebCore::URL& responseURL, int responseStatus) override; + void streamDidReceiveResponse(uint64_t streamID, const WebCore::URL& responseURL, uint32_t streamLength, + uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName) override; + void streamDidReceiveData(uint64_t streamID, const char* bytes, int length) override; + void streamDidFinishLoading(uint64_t streamID) override; + void streamDidFail(uint64_t streamID, bool wasCancelled) override; + void manualStreamDidReceiveResponse(const WebCore::URL& responseURL, uint32_t streamLength, + uint32_t lastModifiedTime, const String& mimeType, const String& headers, const String& suggestedFileName) override; + void manualStreamDidReceiveData(const char* bytes, int length) override; + void manualStreamDidFinishLoading() override; + void manualStreamDidFail(bool wasCancelled) override; - virtual bool handleMouseEvent(const WebMouseEvent&); - virtual bool handleWheelEvent(const WebWheelEvent&); - virtual bool handleMouseEnterEvent(const WebMouseEvent&); - virtual bool handleMouseLeaveEvent(const WebMouseEvent&); - virtual bool handleContextMenuEvent(const WebMouseEvent&); - virtual bool handleKeyboardEvent(const WebKeyboardEvent&); - virtual void setFocus(bool); - - virtual bool handleEditingCommand(const String& commandName, const String& argument) override; - virtual bool isEditingCommandEnabled(const String&) override; - - virtual bool shouldAllowScripting() override; - virtual bool shouldAllowNavigationFromDrags() override; + bool handleMouseEvent(const WebMouseEvent&) override; + bool handleWheelEvent(const WebWheelEvent&) override; + bool handleMouseEnterEvent(const WebMouseEvent&) override; + bool handleMouseLeaveEvent(const WebMouseEvent&) override; + bool handleContextMenuEvent(const WebMouseEvent&) override; + bool handleKeyboardEvent(const WebKeyboardEvent&) override; + void setFocus(bool) override; + + bool handleEditingCommand(const String& commandName, const String& argument) override; + bool isEditingCommandEnabled(const String&) override; + + bool shouldAllowScripting() override; + bool shouldAllowNavigationFromDrags() override; - virtual bool handlesPageScaleFactor() override; + bool handlesPageScaleFactor() const override; - virtual NPObject* pluginScriptableNPObject(); + NPObject* pluginScriptableNPObject() override; - virtual unsigned countFindMatches(const String&, WebCore::FindOptions, unsigned maxMatchCount) override; - virtual bool findString(const String&, WebCore::FindOptions, unsigned maxMatchCount) override; + unsigned countFindMatches(const String&, WebCore::FindOptions, unsigned maxMatchCount) override; + bool findString(const String&, WebCore::FindOptions, unsigned maxMatchCount) override; + + void windowFocusChanged(bool) override; + void windowVisibilityChanged(bool) override; -#if PLATFORM(MAC) - virtual void windowFocusChanged(bool); - virtual void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates); - virtual void windowVisibilityChanged(bool); +#if PLATFORM(COCOA) + void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) override; - virtual uint64_t pluginComplexTextInputIdentifier() const; - virtual void sendComplexTextInput(const String& textInput); - virtual void setLayerHostingMode(LayerHostingMode) override; + uint64_t pluginComplexTextInputIdentifier() const override; + void sendComplexTextInput(const String& textInput) override; + void setLayerHostingMode(LayerHostingMode) override; void pluginFocusOrWindowFocusChanged(); void setComplexTextInputEnabled(bool); @@ -237,40 +251,31 @@ private: void updatePluginLayer(); #endif - virtual void contentsScaleFactorChanged(float); - virtual void storageBlockingStateChanged(bool); - virtual void privateBrowsingStateChanged(bool); - virtual bool getFormValue(String& formValue); - virtual bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity); - virtual WebCore::Scrollbar* horizontalScrollbar(); - virtual WebCore::Scrollbar* verticalScrollbar(); + void contentsScaleFactorChanged(float) override; + void storageBlockingStateChanged(bool) override; + void privateBrowsingStateChanged(bool) override; + bool getFormValue(String& formValue) override; + bool handleScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity) override; + WebCore::Scrollbar* horizontalScrollbar() override; + WebCore::Scrollbar* verticalScrollbar() override; - virtual bool supportsSnapshotting() const; - - // Convert the given point from plug-in coordinates to root view coordinates. - virtual WebCore::IntPoint convertToRootView(const WebCore::IntPoint&) const override; + bool supportsSnapshotting() const override; // Convert the given point from root view coordinates to plug-in coordinates. Returns false if the point can't be // converted (if the transformation matrix isn't invertible). bool convertFromRootView(const WebCore::IntPoint& pointInRootViewCoordinates, WebCore::IntPoint& pointInPluginCoordinates); - virtual PassRefPtr<WebCore::SharedBuffer> liveResourceData() const override; - - virtual bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) override { return false; } + RefPtr<WebCore::SharedBuffer> liveResourceData() const override; - virtual String getSelectionString() const override { return String(); } + bool performDictionaryLookupAtLocation(const WebCore::FloatPoint&) override { return false; } - void updateNPNPrivateMode(); + String getSelectionString() const override { return String(); } + String getSelectionForWordAtPoint(const WebCore::FloatPoint&) const override { return String(); } + bool existingSelectionContainsPoint(const WebCore::FloatPoint&) const override { return false; } -#if PLUGIN_ARCHITECTURE(WIN) - static BOOL WINAPI hookedTrackPopupMenu(HMENU, UINT uFlags, int x, int y, int nReserved, HWND, const RECT*); - void scheduleWindowedGeometryUpdate(); -#endif + void mutedStateChanged(bool) override; -#if PLUGIN_ARCHITECTURE(X11) - bool platformPostInitializeWindowed(bool needsXEmbed, uint64_t windowID); - bool platformPostInitializeWindowless(); -#endif + void updateNPNPrivateMode(); uint64_t m_nextRequestID; @@ -279,6 +284,7 @@ private: typedef HashMap<uint64_t, RefPtr<NetscapePluginStream>> StreamsMap; StreamsMap m_streams; + HashMap<void*, std::pair<RefPtr<NetscapePluginStream>, String>> m_redirects; RefPtr<NetscapePluginModule> m_pluginModule; NPP_t m_npp; @@ -292,8 +298,9 @@ private: // A transform that can be used to convert from root view coordinates to plug-in coordinates. WebCore::AffineTransform m_pluginToRootViewTransform; - // FIXME: Get rid of these. +#if PLUGIN_ARCHITECTURE(X11) WebCore::IntRect m_frameRectInWindowCoordinates; +#endif CString m_userAgent; @@ -365,14 +372,12 @@ private: // if we can tell the plug-in that we support the updated Cocoa text input specification. bool m_hasHandledAKeyDownEvent; - // The number of NPCocoaEventKeyUp events that should be ignored. + // The number of NPCocoaEventKeyUp events that should be ignored. unsigned m_ignoreNextKeyUpEventCounter; WebCore::IntRect m_windowFrameInScreenCoordinates; WebCore::IntRect m_viewFrameInWindowCoordinates; - RetainPtr<WKNPAPIPlugInContainer> m_plugInContainer; - #ifndef NP_NO_CARBON void nullEventTimerFired(); @@ -381,23 +386,15 @@ private: RunLoop::Timer<NetscapePlugin> m_nullEventTimer; NP_CGContext m_npCGContext; #endif -#elif PLUGIN_ARCHITECTURE(WIN) - HWND m_window; - HWND m_contextMenuOwnerWindow; #elif PLUGIN_ARCHITECTURE(X11) - Pixmap m_drawable; - Display* m_pluginDisplay; -#if PLATFORM(GTK) - GtkWidget* m_platformPluginWidget; -#endif - -public: // Need to call it in the NPN_GetValue browser callback. - static Display* x11HostDisplay(); + std::unique_ptr<NetscapePluginUnix> m_impl; #endif }; } // namespace WebKit +SPECIALIZE_TYPE_TRAITS_PLUGIN(NetscapePlugin, NetscapePluginType) + #endif // ENABLE(NETSCAPE_PLUGIN_API) #endif // NetscapePlugin_h diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp index 02cda26fa..0cd3688c3 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp @@ -59,7 +59,7 @@ void NetscapePlugin::platformVisibilityDidChange() { } -void NetscapePlugin::platformPaint(GraphicsContext*, const IntRect&, bool) +void NetscapePlugin::platformPaint(GraphicsContext&, const IntRect&, bool) { } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp index b19c12b6a..7d54d88c7 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp @@ -30,7 +30,6 @@ #include "NetscapePlugin.h" #include <utility> -#include <wtf/PassOwnPtr.h> #include <wtf/Vector.h> using namespace WebCore; @@ -63,6 +62,14 @@ NetscapePluginStream::~NetscapePluginStream() ASSERT(m_fileHandle == invalidPlatformFileHandle); } +void NetscapePluginStream::willSendRequest(const URL& requestURL, const URL& redirectResponseURL, int redirectResponseStatus) +{ + Ref<NetscapePluginStream> protect(*this); + + if (redirectResponseStatus >= 300 && redirectResponseStatus < 400) + m_plugin->registerRedirect(this, requestURL, redirectResponseStatus, m_notificationData); +} + void NetscapePluginStream::didReceiveResponse(const URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers) { // Starting the stream could cause the plug-in stream to go away so we keep a reference to it here. @@ -187,7 +194,7 @@ void NetscapePluginStream::deliverData(const char* bytes, int length) if (m_transferMode != NP_ASFILEONLY) { if (!m_deliveryData) - m_deliveryData = adoptPtr(new Vector<uint8_t>); + m_deliveryData = std::make_unique<Vector<uint8_t>>(); m_deliveryData->reserveCapacity(m_deliveryData->size() + length); m_deliveryData->append(bytes, length); @@ -339,6 +346,11 @@ void NetscapePluginStream::stop(NPReason reason) notifyAndDestroyStream(reason); } +void NetscapePluginStream::setURL(const String& newURLString) +{ + m_requestURLString = newURLString; +} + void NetscapePluginStream::cancel() { m_plugin->cancelStreamLoad(this); diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h index ad82c7aa3..7c7045fd3 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.h @@ -30,6 +30,7 @@ #include <WebCore/FileSystem.h> #include <WebCore/npruntime_internal.h> +#include <memory> #include <wtf/Forward.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> @@ -47,15 +48,16 @@ class NetscapePlugin; class NetscapePluginStream : public RefCounted<NetscapePluginStream> { public: - static PassRefPtr<NetscapePluginStream> create(PassRefPtr<NetscapePlugin> plugin, uint64_t streamID, const String& requestURLString, bool sendNotification, void* notificationData) + static Ref<NetscapePluginStream> create(PassRefPtr<NetscapePlugin> plugin, uint64_t streamID, const String& requestURLString, bool sendNotification, void* notificationData) { - return adoptRef(new NetscapePluginStream(plugin, streamID, requestURLString, sendNotification, notificationData)); + return adoptRef(*new NetscapePluginStream(plugin, streamID, requestURLString, sendNotification, notificationData)); } ~NetscapePluginStream(); uint64_t streamID() const { return m_streamID; } const NPStream* npStream() const { return &m_npStream; } + void willSendRequest(const WebCore::URL& requestURL, const WebCore::URL& redirectResponseURL, int redirectResponseStatus); void didReceiveResponse(const WebCore::URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers); void didReceiveData(const char* bytes, int length); @@ -66,6 +68,7 @@ public: void stop(NPReason); NPError destroy(NPReason); + void setURL(const String& newURLString); private: NetscapePluginStream(PassRefPtr<NetscapePlugin>, uint64_t streamID, const String& requestURLString, bool sendNotification, void* notificationData); @@ -106,7 +109,7 @@ private: CString m_headers; RunLoop::Timer<NetscapePluginStream> m_deliveryDataTimer; - OwnPtr< Vector<uint8_t>> m_deliveryData; + std::unique_ptr<Vector<uint8_t>> m_deliveryData; bool m_stopStreamWhenDoneDelivering; }; diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.cpp new file mode 100644 index 000000000..8b8eaa0bc --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * 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 "NetscapePlugin.h" + +#if PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API) + +#include "NetscapePluginX11.h" +#include "WebEvent.h" +#include <WebCore/NotImplemented.h> +#include <WebCore/PlatformDisplay.h> + +using namespace WebCore; + +namespace WebKit { + +void NetscapePlugin::platformPreInitialize() +{ +} + +bool NetscapePlugin::platformPostInitialize() +{ +#if PLATFORM(X11) + if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::X11) { + m_impl = NetscapePluginX11::create(*this); + if (!m_impl) + return false; + } +#endif + + // Windowed plugins need a platform implementation. + if (!m_impl) + return !m_isWindowed; + + m_npWindow.type = m_impl->windowType(); + m_npWindow.window = m_impl->window(); + m_npWindow.ws_info = m_impl->windowSystemInfo(); + callSetWindow(); + return true; +} + +void NetscapePlugin::platformDestroy() +{ + m_impl = nullptr; +} + +bool NetscapePlugin::platformInvalidate(const IntRect&) +{ + notImplemented(); + return false; +} + +void NetscapePlugin::platformGeometryDidChange() +{ + if (!m_impl) + return; + m_impl->geometryDidChange(); +} + +void NetscapePlugin::platformVisibilityDidChange() +{ + if (!m_isWindowed || !m_impl) + return; + + m_impl->visibilityDidChange(); +} + +void NetscapePlugin::platformPaint(GraphicsContext& context, const IntRect& dirtyRect, bool /*isSnapshot*/) +{ + if (m_isWindowed || !m_impl) + return; + + if (!m_isStarted) { + // FIXME: we should paint a missing plugin icon. + return; + } + + m_impl->paint(context, dirtyRect); +} + +bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& event) +{ + if (m_isWindowed || !m_impl) + return false; + + if ((event.type() == WebEvent::MouseDown || event.type() == WebEvent::MouseUp) + && event.button() == WebMouseEvent::RightButton + && quirks().contains(PluginQuirks::IgnoreRightClickInWindowlessMode)) + return false; + + return m_impl->handleMouseEvent(event); +} + +bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent& event) +{ + if (m_isWindowed || !m_impl) + return false; + + return m_impl->handleWheelEvent(event); +} + +void NetscapePlugin::platformSetFocus(bool focusIn) +{ + if (m_isWindowed || !m_impl) + return; + + m_impl->setFocus(focusIn); +} + +bool NetscapePlugin::wantsPluginRelativeNPWindowCoordinates() +{ + return true; +} + +bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent& event) +{ + if (m_isWindowed || !m_impl) + return false; + + return m_impl->handleMouseEnterEvent(event); +} + +bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent& event) +{ + if (m_isWindowed || !m_impl) + return false; + + return m_impl->handleMouseLeaveEvent(event); +} + +bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent& event) +{ + // We don't generate other types of keyboard events via WebEventFactory. + ASSERT(event.type() == WebEvent::KeyDown || event.type() == WebEvent::KeyUp); + + if (m_isWindowed || !m_impl) + return false; + + return m_impl->handleKeyboardEvent(event); +} + +} // namespace WebKit + +#endif // PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API) diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.h b/Source/WebKit2/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.h new file mode 100644 index 000000000..efa6cd0ce --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/unix/NetscapePluginUnix.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2015 Igalia S.L. + * + * 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. + */ + +#ifndef NetscapePluginUnix_h +#define NetscapePluginUnix_h + +#if PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API) + +#include <WebCore/npruntime_internal.h> + +namespace WebCore { +class GraphicsContext; +class IntRect; +} + +namespace WebKit { + +class WebKeyboardEvent; +class WebMouseEvent; +class WebWheelEvent; + +class NetscapePluginUnix { +public: + virtual ~NetscapePluginUnix() { } + virtual NPWindowType windowType() const = 0; + virtual void* window() const = 0; + virtual NPSetWindowCallbackStruct* windowSystemInfo() = 0; + virtual void geometryDidChange() = 0; + virtual void visibilityDidChange() = 0; + virtual void paint(WebCore::GraphicsContext&, const WebCore::IntRect&) = 0; + virtual bool handleMouseEvent(const WebMouseEvent&) = 0; + virtual bool handleWheelEvent(const WebWheelEvent&) = 0; + virtual bool handleMouseEnterEvent(const WebMouseEvent&) = 0; + virtual bool handleMouseLeaveEvent(const WebMouseEvent&) = 0; + virtual bool handleKeyboardEvent(const WebKeyboardEvent&) = 0; + virtual void setFocus(bool) = 0; +}; + +} // namespace WebKit + +#endif // PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API) + +#endif // NetscapePluginUnix_h diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp index c22bc74a2..2bed46aab 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp @@ -25,14 +25,17 @@ */ #include "config.h" +#include "NetscapePluginX11.h" + #if PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API) #include "NetscapePlugin.h" - #include "PluginController.h" #include "WebEvent.h" #include <WebCore/GraphicsContext.h> #include <WebCore/NotImplemented.h> +#include <WebCore/PlatformDisplayX11.h> +#include <WebCore/XUniquePtr.h> #if PLATFORM(GTK) #include <gtk/gtk.h> @@ -41,8 +44,6 @@ #endif #include <gdk/gdkx.h> #include <WebCore/GtkVersioning.h> -#elif PLATFORM(EFL) && defined(HAVE_ECORE_X) -#include <Ecore_X.h> #endif #if USE(CAIRO) @@ -55,16 +56,19 @@ using namespace WebCore; namespace WebKit { +static inline Display* x11HostDisplay() +{ + return downcast<PlatformDisplayX11>(PlatformDisplay::sharedDisplay()).native(); +} + static Display* getPluginDisplay() { #if PLATFORM(GTK) // Since we're a gdk/gtk app, we'll (probably?) have the same X connection as any gdk-based // plugins, so we can return that. We might want to add other implementations here later. return GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); -#elif PLATFORM(EFL) && defined(HAVE_ECORE_X) - return static_cast<Display*>(ecore_x_display_get()); #else - return 0; + return nullptr; #endif } @@ -72,8 +76,6 @@ static inline int x11Screen() { #if PLATFORM(GTK) return gdk_screen_get_number(gdk_screen_get_default()); -#elif PLATFORM(EFL) && defined(HAVE_ECORE_X) - return ecore_x_screen_index_get(ecore_x_default_screen_get()); #else return 0; #endif @@ -83,8 +85,6 @@ static inline int displayDepth() { #if PLATFORM(GTK) return gdk_visual_get_depth(gdk_screen_get_system_visual(gdk_screen_get_default())); -#elif PLATFORM(EFL) && defined(HAVE_ECORE_X) - return ecore_x_default_depth_get(NetscapePlugin::x11HostDisplay(), ecore_x_default_screen_get()); #else return 0; #endif @@ -94,19 +94,6 @@ static inline unsigned long rootWindowID() { #if PLATFORM(GTK) return GDK_ROOT_WINDOW(); -#elif PLATFORM(EFL) && defined(HAVE_ECORE_X) - return ecore_x_window_root_first_get(); -#else - return 0; -#endif -} - -Display* NetscapePlugin::x11HostDisplay() -{ -#if PLATFORM(GTK) - return GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); -#elif PLATFORM(EFL) && defined(HAVE_ECORE_X) - return static_cast<Display*>(ecore_x_display_get()); #else return 0; #endif @@ -123,187 +110,165 @@ static gboolean socketPlugRemovedCallback(GtkSocket*) } #endif -bool NetscapePlugin::platformPostInitializeWindowed(bool needsXEmbed, uint64_t windowID) +std::unique_ptr<NetscapePluginX11> NetscapePluginX11::create(NetscapePlugin& plugin) { - m_npWindow.type = NPWindowTypeWindow; - if (!needsXEmbed) { +#if PLATFORM(GTK) + uint64_t windowID = 0; +#endif + if (plugin.isWindowed()) { +#if PLATFORM(GTK) + // NPPVplugiNeedsXEmbed is a boolean value, but at least the + // Flash player plugin is using an 'int' instead. + int needsXEmbed = 0; + plugin.NPP_GetValue(NPPVpluginNeedsXEmbed, &needsXEmbed); + if (needsXEmbed) { + windowID = plugin.controller()->createPluginContainer(); + if (!windowID) + return nullptr; + } else { + notImplemented(); + return nullptr; + } +#else notImplemented(); - return false; + return nullptr; +#endif } - Display* display = x11HostDisplay(); + Display* display = getPluginDisplay(); + if (!display) + return nullptr; #if PLATFORM(GTK) - // It seems flash needs the socket to be in the same process, - // I guess it uses gdk_window_lookup(), so we create a new socket here - // containing a plug with the UI process socket embedded. - m_platformPluginWidget = gtk_plug_new(static_cast<Window>(windowID)); - GtkWidget* socket = gtk_socket_new(); - g_signal_connect(socket, "plug-removed", G_CALLBACK(socketPlugRemovedCallback), 0); - gtk_container_add(GTK_CONTAINER(m_platformPluginWidget), socket); - gtk_widget_show(socket); - gtk_widget_show(m_platformPluginWidget); - - m_npWindow.window = GINT_TO_POINTER(gtk_socket_get_id(GTK_SOCKET(socket))); - GdkWindow* window = gtk_widget_get_window(socket); - NPSetWindowCallbackStruct* callbackStruct = static_cast<NPSetWindowCallbackStruct*>(m_npWindow.ws_info); - callbackStruct->display = GDK_WINDOW_XDISPLAY(window); - callbackStruct->visual = GDK_VISUAL_XVISUAL(gdk_window_get_visual(window)); - callbackStruct->depth = gdk_visual_get_depth(gdk_window_get_visual(window)); - callbackStruct->colormap = XCreateColormap(display, GDK_ROOT_WINDOW(), callbackStruct->visual, AllocNone); -#else - UNUSED_PARAM(windowID); + if (plugin.isWindowed()) + return std::make_unique<NetscapePluginX11>(plugin, display, windowID); #endif - XFlush(display); - - callSetWindow(); - - return true; + return std::make_unique<NetscapePluginX11>(plugin, display); } -bool NetscapePlugin::platformPostInitializeWindowless() +NetscapePluginX11::NetscapePluginX11(NetscapePlugin& plugin, Display* display) + : m_plugin(plugin) + , m_pluginDisplay(display) { - Display* display = x11HostDisplay(); - m_npWindow.type = NPWindowTypeDrawable; - m_npWindow.window = 0; - + Display* hostDisplay = x11HostDisplay(); int depth = displayDepth(); - - NPSetWindowCallbackStruct* callbackStruct = static_cast<NPSetWindowCallbackStruct*>(m_npWindow.ws_info); - callbackStruct->display = display; - callbackStruct->depth = depth; + m_setWindowCallbackStruct.display = hostDisplay; + m_setWindowCallbackStruct.depth = depth; XVisualInfo visualTemplate; visualTemplate.screen = x11Screen(); visualTemplate.depth = depth; visualTemplate.c_class = TrueColor; int numMatching; - XVisualInfo* visualInfo = XGetVisualInfo(display, VisualScreenMask | VisualDepthMask | VisualClassMask, - &visualTemplate, &numMatching); + XUniquePtr<XVisualInfo> visualInfo(XGetVisualInfo(hostDisplay, VisualScreenMask | VisualDepthMask | VisualClassMask, &visualTemplate, &numMatching)); ASSERT(visualInfo); - Visual* visual = visualInfo[0].visual; + Visual* visual = visualInfo.get()[0].visual; ASSERT(visual); - XFree(visualInfo); - - callbackStruct->visual = visual; - callbackStruct->colormap = XCreateColormap(display, rootWindowID(), visual, AllocNone); - - callSetWindow(); - return true; + m_setWindowCallbackStruct.visual = visual; + m_setWindowCallbackStruct.colormap = XCreateColormap(hostDisplay, rootWindowID(), visual, AllocNone); } -void NetscapePlugin::platformPreInitialize() -{ -} - -bool NetscapePlugin::platformPostInitialize() +#if PLATFORM(GTK) +NetscapePluginX11::NetscapePluginX11(NetscapePlugin& plugin, Display* display, uint64_t windowID) + : m_plugin(plugin) + , m_pluginDisplay(display) + , m_windowID(windowID) { - uint64_t windowID = 0; - // NPPVpluginNeedsXEmbed is a boolean value, but at least the - // Flash player plugin is using an 'int' instead. - int needsXEmbed = 0; - if (m_isWindowed) { - NPP_GetValue(NPPVpluginNeedsXEmbed, &needsXEmbed); - if (needsXEmbed) { - windowID = controller()->createPluginContainer(); - if (!windowID) - return false; - } else { - notImplemented(); - return false; - } - } + // It seems flash needs the socket to be in the same process, + // I guess it uses gdk_window_lookup(), so we create a new socket here + // containing a plug with the UI process socket embedded. + m_platformPluginWidget = gtk_plug_new(static_cast<Window>(windowID)); - if (!(m_pluginDisplay = getPluginDisplay())) - return false; + // Hide the GtkPlug on delete-event since we assume the widget is valid while the plugin is active. + // platformDestroy() will be called anyway right after the delete-event. + g_signal_connect(m_platformPluginWidget, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), nullptr); - NPSetWindowCallbackStruct* callbackStruct = new NPSetWindowCallbackStruct; - callbackStruct->type = 0; - m_npWindow.ws_info = callbackStruct; + GtkWidget* socket = gtk_socket_new(); + // Do not show the plug widget until the socket is connected. + g_signal_connect_swapped(socket, "plug-added", G_CALLBACK(gtk_widget_show), m_platformPluginWidget); + g_signal_connect(socket, "plug-removed", G_CALLBACK(socketPlugRemovedCallback), nullptr); + gtk_container_add(GTK_CONTAINER(m_platformPluginWidget), socket); + gtk_widget_show(socket); - if (m_isWindowed) - return platformPostInitializeWindowed(needsXEmbed, windowID); + Display* hostDisplay = x11HostDisplay(); + m_npWindowID = gtk_socket_get_id(GTK_SOCKET(socket)); + GdkWindow* window = gtk_widget_get_window(socket); + m_setWindowCallbackStruct.display = GDK_WINDOW_XDISPLAY(window); + m_setWindowCallbackStruct.visual = GDK_VISUAL_XVISUAL(gdk_window_get_visual(window)); + m_setWindowCallbackStruct.depth = gdk_visual_get_depth(gdk_window_get_visual(window)); + m_setWindowCallbackStruct.colormap = XCreateColormap(hostDisplay, GDK_ROOT_WINDOW(), m_setWindowCallbackStruct.visual, AllocNone); - return platformPostInitializeWindowless(); + XFlush(hostDisplay); } +#endif -void NetscapePlugin::platformDestroy() +NetscapePluginX11::~NetscapePluginX11() { - NPSetWindowCallbackStruct* callbackStruct = static_cast<NPSetWindowCallbackStruct*>(m_npWindow.ws_info); - Display* hostDisplay = x11HostDisplay(); - XFreeColormap(hostDisplay, callbackStruct->colormap); - delete callbackStruct; + XFreeColormap(x11HostDisplay(), m_setWindowCallbackStruct.colormap); - if (m_drawable) { - XFreePixmap(hostDisplay, m_drawable); - m_drawable = 0; - } + m_drawable.reset(); #if PLATFORM(GTK) - if (m_platformPluginWidget) { + if (m_platformPluginWidget) gtk_widget_destroy(m_platformPluginWidget); - m_platformPluginWidget = 0; - } #endif } -bool NetscapePlugin::platformInvalidate(const IntRect&) +NPWindowType NetscapePluginX11::windowType() const { - notImplemented(); - return false; + return m_plugin.isWindowed() ? NPWindowTypeWindow : NPWindowTypeDrawable; +} + +void* NetscapePluginX11::window() const +{ +#if PLATFORM(GTK) + return m_plugin.isWindowed() ? GINT_TO_POINTER(m_npWindowID) : nullptr; +#else + return nullptr; +#endif } -void NetscapePlugin::platformGeometryDidChange() +void NetscapePluginX11::geometryDidChange() { - if (m_isWindowed) { + if (m_plugin.isWindowed()) { uint64_t windowID = 0; #if PLATFORM(GTK) + if (!gtk_plug_get_embedded(GTK_PLUG(m_platformPluginWidget))) + return; windowID = static_cast<uint64_t>(GDK_WINDOW_XID(gtk_plug_get_socket_window(GTK_PLUG(m_platformPluginWidget)))); #endif - controller()->windowedPluginGeometryDidChange(m_frameRectInWindowCoordinates, m_clipRect, windowID); + m_plugin.controller()->windowedPluginGeometryDidChange(m_plugin.frameRectInWindowCoordinates(), m_plugin.clipRect(), windowID); return; } - Display* display = x11HostDisplay(); - if (m_drawable) - XFreePixmap(display, m_drawable); - - if (m_pluginSize.isEmpty()) { - m_drawable = 0; + m_drawable.reset(); + if (m_plugin.size().isEmpty()) return; - } - - m_drawable = XCreatePixmap(display, rootWindowID(), m_pluginSize.width(), m_pluginSize.height(), displayDepth()); - XSync(display, false); // Make sure that the server knows about the Drawable. + m_drawable = XCreatePixmap(x11HostDisplay(), rootWindowID(), m_plugin.size().width(), m_plugin.size().height(), displayDepth()); + XSync(x11HostDisplay(), false); // Make sure that the server knows about the Drawable. } -void NetscapePlugin::platformVisibilityDidChange() +void NetscapePluginX11::visibilityDidChange() { - if (!m_isWindowed) - return; - + ASSERT(m_plugin.isWindowed()); uint64_t windowID = 0; #if PLATFORM(GTK) + if (!gtk_plug_get_embedded(GTK_PLUG(m_platformPluginWidget))) + return; windowID = static_cast<uint64_t>(GDK_WINDOW_XID(gtk_plug_get_socket_window(GTK_PLUG(m_platformPluginWidget)))); #endif - controller()->windowedPluginVisibilityDidChange(m_isVisible, windowID); - controller()->windowedPluginGeometryDidChange(m_frameRectInWindowCoordinates, m_clipRect, windowID); + m_plugin.controller()->windowedPluginVisibilityDidChange(m_plugin.isVisible(), windowID); + m_plugin.controller()->windowedPluginGeometryDidChange(m_plugin.frameRectInWindowCoordinates(), m_plugin.clipRect(), windowID); } -void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirtyRect, bool /*isSnapshot*/) +void NetscapePluginX11::paint(GraphicsContext& context, const IntRect& dirtyRect) { - if (m_isWindowed) - return; - - if (!m_isStarted) { - // FIXME: we should paint a missing plugin icon. - return; - } + ASSERT(!m_plugin.isWindowed()); - if (context->paintingDisabled() || !m_drawable) + if (context.paintingDisabled() || !m_drawable) return; XEvent xevent; @@ -311,7 +276,7 @@ void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirt XGraphicsExposeEvent& exposeEvent = xevent.xgraphicsexpose; exposeEvent.type = GraphicsExpose; exposeEvent.display = x11HostDisplay(); - exposeEvent.drawable = m_drawable; + exposeEvent.drawable = m_drawable.get(); IntRect exposedRect(dirtyRect); exposeEvent.x = exposedRect.x(); @@ -322,18 +287,15 @@ void NetscapePlugin::platformPaint(GraphicsContext* context, const IntRect& dirt exposeEvent.width = exposedRect.width(); exposeEvent.height = exposedRect.height(); - NPP_HandleEvent(&xevent); + m_plugin.NPP_HandleEvent(&xevent); if (m_pluginDisplay != x11HostDisplay()) XSync(m_pluginDisplay, false); -#if PLATFORM(GTK) || (PLATFORM(EFL) && USE(CAIRO)) - RefPtr<cairo_surface_t> drawableSurface = adoptRef(cairo_xlib_surface_create(m_pluginDisplay, - m_drawable, - static_cast<NPSetWindowCallbackStruct*>(m_npWindow.ws_info)->visual, - m_pluginSize.width(), - m_pluginSize.height())); - cairo_t* cr = context->platformContext()->cr(); +#if PLATFORM(GTK) + RefPtr<cairo_surface_t> drawableSurface = adoptRef(cairo_xlib_surface_create(m_pluginDisplay, m_drawable.get(), + m_setWindowCallbackStruct.visual, m_plugin.size().width(), m_plugin.size().height())); + cairo_t* cr = context.platformContext()->cr(); cairo_save(cr); cairo_set_source_surface(cr, drawableSurface.get(), 0, 0); @@ -354,7 +316,7 @@ static inline void initializeXEvent(XEvent& event) memset(&event, 0, sizeof(XEvent)); event.xany.serial = 0; event.xany.send_event = false; - event.xany.display = NetscapePlugin::x11HostDisplay(); + event.xany.display = x11HostDisplay(); event.xany.window = 0; } @@ -452,15 +414,9 @@ static inline void setXCrossingEventFields(XEvent& xEvent, const WebMouseEvent& xCrossing.focus = false; } -bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& event) +bool NetscapePluginX11::handleMouseEvent(const WebMouseEvent& event) { - if (m_isWindowed) - return false; - - if ((event.type() == WebEvent::MouseDown || event.type() == WebEvent::MouseUp) - && event.button() == WebMouseEvent::RightButton - && quirks().contains(PluginQuirks::IgnoreRightClickInWindowlessMode)) - return false; + ASSERT(!m_plugin.isWindowed()); XEvent xEvent; initializeXEvent(xEvent); @@ -468,22 +424,20 @@ bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& event) switch (event.type()) { case WebEvent::MouseDown: case WebEvent::MouseUp: - setXButtonEventFields(xEvent, event, convertToRootView(IntPoint())); + setXButtonEventFields(xEvent, event, m_plugin.convertToRootView(IntPoint())); break; case WebEvent::MouseMove: - setXMotionEventFields(xEvent, event, convertToRootView(IntPoint())); + setXMotionEventFields(xEvent, event, m_plugin.convertToRootView(IntPoint())); break; + case WebEvent::MouseForceChanged: + case WebEvent::MouseForceDown: + case WebEvent::MouseForceUp: case WebEvent::NoType: case WebEvent::Wheel: case WebEvent::KeyDown: case WebEvent::KeyUp: case WebEvent::RawKeyDown: case WebEvent::Char: -#if ENABLE(GESTURE_EVENTS) - case WebEvent::GestureScrollBegin: - case WebEvent::GestureScrollEnd: - case WebEvent::GestureSingleTap: -#endif #if ENABLE(TOUCH_EVENTS) case WebEvent::TouchStart: case WebEvent::TouchMove: @@ -493,7 +447,7 @@ bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& event) return false; } - return !NPP_HandleEvent(&xEvent); + return !m_plugin.NPP_HandleEvent(&xEvent); } // We undefine these constants in npruntime_internal.h to avoid collision @@ -503,22 +457,20 @@ const int kKeyReleaseType = 3; const int kFocusInType = 9; const int kFocusOutType = 10; -bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent& event) +bool NetscapePluginX11::handleWheelEvent(const WebWheelEvent& event) { - if (m_isWindowed) - return false; + ASSERT(!m_plugin.isWindowed()); XEvent xEvent; initializeXEvent(xEvent); - setXButtonEventFieldsByWebWheelEvent(xEvent, event, convertToRootView(IntPoint())); + setXButtonEventFieldsByWebWheelEvent(xEvent, event, m_plugin.convertToRootView(IntPoint())); - return !NPP_HandleEvent(&xEvent); + return !m_plugin.NPP_HandleEvent(&xEvent); } -void NetscapePlugin::platformSetFocus(bool focusIn) +void NetscapePluginX11::setFocus(bool focusIn) { - if (m_isWindowed) - return; + ASSERT(!m_plugin.isWindowed()); XEvent xEvent; initializeXEvent(xEvent); @@ -527,36 +479,29 @@ void NetscapePlugin::platformSetFocus(bool focusIn) focusEvent.mode = NotifyNormal; focusEvent.detail = NotifyDetailNone; - NPP_HandleEvent(&xEvent); -} - -bool NetscapePlugin::wantsPluginRelativeNPWindowCoordinates() -{ - return true; + m_plugin.NPP_HandleEvent(&xEvent); } -bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent& event) +bool NetscapePluginX11::handleMouseEnterEvent(const WebMouseEvent& event) { - if (m_isWindowed) - return false; + ASSERT(!m_plugin.isWindowed()); XEvent xEvent; initializeXEvent(xEvent); - setXCrossingEventFields(xEvent, event, convertToRootView(IntPoint()), EnterNotify); + setXCrossingEventFields(xEvent, event, m_plugin.convertToRootView(IntPoint()), EnterNotify); - return !NPP_HandleEvent(&xEvent); + return !m_plugin.NPP_HandleEvent(&xEvent); } -bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent& event) +bool NetscapePluginX11::handleMouseLeaveEvent(const WebMouseEvent& event) { - if (m_isWindowed) - return false; + ASSERT(!m_plugin.isWindowed()); XEvent xEvent; initializeXEvent(xEvent); - setXCrossingEventFields(xEvent, event, convertToRootView(IntPoint()), LeaveNotify); + setXCrossingEventFields(xEvent, event, m_plugin.convertToRootView(IntPoint()), LeaveNotify); - return !NPP_HandleEvent(&xEvent); + return !m_plugin.NPP_HandleEvent(&xEvent); } static inline void setXKeyEventFields(XEvent& xEvent, const WebKeyboardEvent& webEvent) @@ -579,8 +524,9 @@ static inline void setXKeyEventFields(XEvent& xEvent, const WebKeyboardEvent& we xKey.y_root = 0; } -bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent& event) +bool NetscapePluginX11::handleKeyboardEvent(const WebKeyboardEvent& event) { + ASSERT(!m_plugin.isWindowed()); // We don't generate other types of keyboard events via WebEventFactory. ASSERT(event.type() == WebEvent::KeyDown || event.type() == WebEvent::KeyUp); @@ -588,7 +534,7 @@ bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent& event) initializeXEvent(xEvent); setXKeyEventFields(xEvent, event); - return !NPP_HandleEvent(&xEvent); + return !m_plugin.NPP_HandleEvent(&xEvent); } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.h b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.h new file mode 100644 index 000000000..0fe50a1a6 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010 University of Szeged + * + * 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. + */ + +#ifndef NetscapePluginX11_h +#define NetscapePluginX11_h + +#if PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API) + +#include "NetscapePluginUnix.h" +#include <WebCore/XUniqueResource.h> + +namespace WebKit { + +class NetscapePlugin; + +class NetscapePluginX11 final : public NetscapePluginUnix { +public: + static std::unique_ptr<NetscapePluginX11> create(NetscapePlugin&); + NetscapePluginX11(NetscapePlugin&, Display*); +#if PLATFORM(GTK) + NetscapePluginX11(NetscapePlugin&, Display*, uint64_t windowID); +#endif + virtual ~NetscapePluginX11(); + +private: + NPWindowType windowType() const override; + void* window() const override; + NPSetWindowCallbackStruct* windowSystemInfo() override { return &m_setWindowCallbackStruct; } + void geometryDidChange() override; + void visibilityDidChange() override; + void paint(WebCore::GraphicsContext&, const WebCore::IntRect&) override; + bool handleMouseEvent(const WebMouseEvent&) override; + bool handleWheelEvent(const WebWheelEvent&) override; + bool handleMouseEnterEvent(const WebMouseEvent&) override; + bool handleMouseLeaveEvent(const WebMouseEvent&) override; + bool handleKeyboardEvent(const WebKeyboardEvent&) override; + void setFocus(bool) override; + + NetscapePlugin& m_plugin; + Display* m_pluginDisplay { nullptr }; + WebCore::XUniquePixmap m_drawable; + NPSetWindowCallbackStruct m_setWindowCallbackStruct; +#if PLATFORM(GTK) + uint64_t m_windowID { 0 }; + unsigned long m_npWindowID { 0 }; + GtkWidget* m_platformPluginWidget { nullptr }; +#endif +}; +} // namespace WebKit + +#endif // PLUGIN_ARCHITECTURE(X11) && ENABLE(NETSCAPE_PLUGIN_API) + +#endif // NetscapePluginX11_h |