diff options
author | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-17 20:18:17 +0000 |
---|---|---|
committer | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-17 20:18:17 +0000 |
commit | b4efc3807ee3e52550130f6495a36a60694575b1 (patch) | |
tree | b89b756dcf8ab23c4f8ab3b271d1ab04c3f22b39 /webkit/glue | |
parent | 8d5f6b1dcbaf5ed5276db88b7c59ba3e85d146ed (diff) | |
download | chromium_src-b4efc3807ee3e52550130f6495a36a60694575b1.zip chromium_src-b4efc3807ee3e52550130f6495a36a60694575b1.tar.gz chromium_src-b4efc3807ee3e52550130f6495a36a60694575b1.tar.bz2 |
Add some initial PP_Var <-> NPObject bindings.
This provides for basic access to the window and element containing the
instance. Enumeration of properties is not implemented.
R=brettw
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/2075005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47444 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue')
-rw-r--r-- | webkit/glue/plugins/pepper_plugin_instance.cc | 52 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_plugin_instance.h | 10 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_var.cc | 320 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_var.h | 26 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_webplugin_impl.cc | 9 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_webplugin_impl.h | 7 |
6 files changed, 380 insertions, 44 deletions
diff --git a/webkit/glue/plugins/pepper_plugin_instance.cc b/webkit/glue/plugins/pepper_plugin_instance.cc index 2de26be..83f68db 100644 --- a/webkit/glue/plugins/pepper_plugin_instance.cc +++ b/webkit/glue/plugins/pepper_plugin_instance.cc @@ -11,14 +11,22 @@ #include "third_party/ppapi/c/pp_event.h" #include "third_party/ppapi/c/pp_rect.h" #include "third_party/ppapi/c/pp_resource.h" +#include "third_party/ppapi/c/pp_var.h" #include "third_party/ppapi/c/ppb_instance.h" #include "third_party/ppapi/c/ppp_instance.h" +#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" +#include "third_party/WebKit/WebKit/chromium/public/WebElement.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" +#include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h" #include "webkit/glue/plugins/pepper_device_context_2d.h" #include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_resource_tracker.h" +#include "webkit/glue/plugins/pepper_var.h" +using WebKit::WebFrame; using WebKit::WebInputEvent; +using WebKit::WebPluginContainer; namespace pepper { @@ -99,6 +107,20 @@ void BuildMouseWheelEvent(const WebInputEvent* event, PP_Event* pp_event) { pp_event->u.wheel.scrollByPage = mouse_wheel_event->scrollByPage; } +PP_Var GetWindowObject(PP_Instance instance_id) { + PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + if (!instance) + return PP_MakeVoid(); + return instance->GetWindowObject(); +} + +PP_Var GetOwnerElementObject(PP_Instance instance_id) { + PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + if (!instance) + return PP_MakeVoid(); + return instance->GetOwnerElementObject(); +} + bool BindGraphicsDeviceContext(PP_Instance instance_id, PP_Resource device_id) { PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); if (!instance) @@ -107,6 +129,8 @@ bool BindGraphicsDeviceContext(PP_Instance instance_id, PP_Resource device_id) { } const PPB_Instance ppb_instance = { + &GetWindowObject, + &GetOwnerElementObject, &BindGraphicsDeviceContext, }; @@ -117,7 +141,8 @@ PluginInstance::PluginInstance(PluginDelegate* delegate, const PPP_Instance* instance_interface) : delegate_(delegate), module_(module), - instance_interface_(instance_interface) { + instance_interface_(instance_interface), + container_(NULL) { DCHECK(delegate); module_->InstanceCreated(this); } @@ -149,6 +174,24 @@ void PluginInstance::Paint(WebKit::WebCanvas* canvas, device_context_2d_->Paint(canvas, plugin_rect, paint_rect); } +PP_Var PluginInstance::GetWindowObject() { + if (!container_) + return PP_MakeVoid(); + + WebFrame* frame = container_->element().document().frame(); + if (!frame) + return PP_MakeVoid(); + + return NPObjectToPPVar(frame->windowObject()); +} + +PP_Var PluginInstance::GetOwnerElementObject() { + if (!container_) + return PP_MakeVoid(); + + return NPObjectToPPVar(container_->scriptableObjectForElement()); +} + bool PluginInstance::BindGraphicsDeviceContext(PP_Resource device_id) { scoped_refptr<Resource> device_resource = ResourceTracker::Get()->GetResource(device_id); @@ -166,10 +209,15 @@ bool PluginInstance::BindGraphicsDeviceContext(PP_Resource device_id) { void PluginInstance::Delete() { instance_interface_->Delete(GetPPInstance()); + + container_ = NULL; } -bool PluginInstance::Initialize(const std::vector<std::string>& arg_names, +bool PluginInstance::Initialize(WebPluginContainer* container, + const std::vector<std::string>& arg_names, const std::vector<std::string>& arg_values) { + container_ = container; + if (!instance_interface_->New(GetPPInstance())) return false; diff --git a/webkit/glue/plugins/pepper_plugin_instance.h b/webkit/glue/plugins/pepper_plugin_instance.h index 3ff3212..b81ad09 100644 --- a/webkit/glue/plugins/pepper_plugin_instance.h +++ b/webkit/glue/plugins/pepper_plugin_instance.h @@ -14,6 +14,7 @@ typedef struct _pp_Instance PP_Instance; typedef struct _pp_Resource PP_Resource; +typedef struct _pp_Var PP_Var; typedef struct _ppb_Instance PPB_Instance; typedef struct _ppp_Instance PPP_Instance; @@ -24,6 +25,7 @@ class Rect; namespace WebKit { struct WebCursorInfo; class WebInputEvent; +class WebPluginContainer; } namespace pepper { @@ -54,11 +56,14 @@ class PluginInstance : public base::RefCounted<PluginInstance> { const gfx::Rect& paint_rect); // PPB_Instance implementation. + PP_Var GetWindowObject(); + PP_Var GetOwnerElementObject(); bool BindGraphicsDeviceContext(PP_Resource device_id); // PPP_Instance pass-through. void Delete(); - bool Initialize(const std::vector<std::string>& arg_names, + bool Initialize(WebKit::WebPluginContainer* container, + const std::vector<std::string>& arg_names, const std::vector<std::string>& arg_values); bool HandleInputEvent(const WebKit::WebInputEvent& event, WebKit::WebCursorInfo* cursor_info); @@ -69,6 +74,9 @@ class PluginInstance : public base::RefCounted<PluginInstance> { scoped_refptr<PluginModule> module_; const PPP_Instance* instance_interface_; + // NULL until we have been initialized. + WebKit::WebPluginContainer* container_; + // The current device context for painting in 2D. scoped_refptr<DeviceContext2D> device_context_2d_; diff --git a/webkit/glue/plugins/pepper_var.cc b/webkit/glue/plugins/pepper_var.cc index 3e11ff2..23894f7 100644 --- a/webkit/glue/plugins/pepper_var.cc +++ b/webkit/glue/plugins/pepper_var.cc @@ -4,35 +4,58 @@ #include "webkit/glue/plugins/pepper_var.h" +#include "base/logging.h" +#include "base/scoped_ptr.h" +#include "base/string_util.h" #include "third_party/ppapi/c/pp_var.h" #include "third_party/ppapi/c/ppb_var.h" +#include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" #include "webkit/glue/plugins/pepper_string.h" +using WebKit::WebBindings; + namespace pepper { namespace { +String* GetStringUnchecked(PP_Var var) { + return reinterpret_cast<String*>(var.value.as_id); +} + +NPObject* GetNPObjectUnchecked(PP_Var var) { + return reinterpret_cast<NPObject*>(var.value.as_id); +} + +NPObject* GetNPObject(PP_Var var) { + if (var.type != PP_VarType_Object) + return NULL; + return GetNPObjectUnchecked(var); +} + void AddRef(PP_Var var) { if (var.type == PP_VarType_String) { - reinterpret_cast<String*>(var.value.as_id)->AddRef(); + GetStringUnchecked(var)->AddRef(); } else if (var.type == PP_VarType_Object) { - // TODO(implement objects). + // TODO(darin): Add thread safety check + WebBindings::retainObject(GetNPObjectUnchecked(var)); } } void Release(PP_Var var) { if (var.type == PP_VarType_String) { - reinterpret_cast<String*>(var.value.as_id)->Release(); + GetStringUnchecked(var)->Release(); } else if (var.type == PP_VarType_Object) { - // TODO(implement objects). + // TODO(darin): Add thread safety check + WebBindings::releaseObject(GetNPObjectUnchecked(var)); } } PP_Var VarFromUtf8(const char* data, uint32_t len) { - PP_Var ret; - ret.type = PP_VarType_String; String* str = new String(data, len); str->AddRef(); // This is for the caller, we return w/ a refcount of 1. + PP_Var ret; + ret.type = PP_VarType_String; + ret.value.as_id = reinterpret_cast<intptr_t>(str); return ret; } @@ -41,77 +64,203 @@ const char* VarToUtf8(PP_Var var, uint32_t* len) { *len = 0; return NULL; } - const std::string& str = - reinterpret_cast<const String*>(var.value.as_id)->value(); + const std::string& str = GetStringUnchecked(var)->value(); *len = static_cast<uint32_t>(str.size()); if (str.empty()) return ""; // Don't return NULL on success. return str.data(); } -bool HasProperty(PP_Var object, +bool HasProperty(PP_Var var, PP_Var name, PP_Var* exception) { - // TODO(brettw) implement this. - return false; + if (exception && exception->type != PP_VarType_Void) + return false; + + NPObject* object = GetNPObject(var); + if (!object) { + // TODO(darin): raise exception + return false; + } + + NPIdentifier identifier = PPVarToNPIdentifier(name); + if (!identifier) { + // TODO(darin): raise exception + return false; + } + + return WebBindings::hasProperty(NULL, object, identifier); } -PP_Var GetProperty(PP_Var object, +PP_Var GetProperty(PP_Var var, PP_Var name, PP_Var* exception) { - // TODO(brettw) implement this. - PP_Var ret; - ret.type = PP_VarType_Void; + if (exception && exception->type != PP_VarType_Void) + return PP_MakeVoid(); + + NPObject* object = GetNPObject(var); + if (!object) { + // TODO(darin): raise exception + return PP_MakeVoid(); + } + + NPIdentifier identifier = PPVarToNPIdentifier(name); + if (!identifier) { + // TODO(darin): raise exception + return PP_MakeVoid(); + } + + NPVariant result; + if (!WebBindings::getProperty(NULL, object, identifier, &result)) { + // TODO(darin): raise exception + return PP_MakeVoid(); + } + + PP_Var ret = NPVariantToPPVar(&result); + WebBindings::releaseVariantValue(&result); return ret; } -void GetAllPropertyNames(PP_Var object, +void GetAllPropertyNames(PP_Var var, uint32_t* property_count, PP_Var** properties, PP_Var* exception) { - // TODO(brettw) implement this. + if (exception && exception->type != PP_VarType_Void) + return; + + // TODO(darin) } -void SetProperty(PP_Var object, +void SetProperty(PP_Var var, PP_Var name, PP_Var value, PP_Var* exception) { - // TODO(brettw) implement this. + if (exception && exception->type != PP_VarType_Void) + return; + + NPObject* object = GetNPObject(var); + if (!object) { + // TODO(darin): raise exception + return; + } + + NPIdentifier identifier = PPVarToNPIdentifier(name); + if (!identifier) { + // TODO(darin): raise exception + return; + } + + NPVariant variant = PPVarToNPVariantNoCopy(value); + WebBindings::setProperty(NULL, object, identifier, &variant); } -void RemoveProperty(PP_Var object, +void RemoveProperty(PP_Var var, PP_Var name, PP_Var* exception) { - // TODO(brettw) implement this. + if (exception && exception->type != PP_VarType_Void) + return; + + NPObject* object = GetNPObject(var); + if (!object) { + // TODO(darin): raise exception + return; + } + + NPIdentifier identifier = PPVarToNPIdentifier(name); + if (!identifier) { + // TODO(darin): raise exception + return; + } + + WebBindings::removeProperty(NULL, object, identifier); } -PP_Var Call(PP_Var object, +PP_Var Call(PP_Var var, PP_Var method_name, int32_t argc, PP_Var* argv, PP_Var* exception) { - // TODO(brettw) implement this. - PP_Var ret; - ret.type = PP_VarType_Void; + if (exception && exception->type != PP_VarType_Void) + return PP_MakeVoid(); + + NPObject* object = GetNPObject(var); + if (!object) { + // TODO(darin): raise exception + return PP_MakeVoid(); + } + + NPIdentifier identifier; + if (method_name.type == PP_VarType_Void) { + identifier = NULL; + } else { + identifier = PPVarToNPIdentifier(method_name); + if (!identifier) { + // TODO(darin): raise exception + return PP_MakeVoid(); + } + } + + scoped_array<NPVariant> args; + if (argc) { + args.reset(new NPVariant[argc]); + for (int32_t i = 0; i < argc; ++i) + args[i] = PPVarToNPVariantNoCopy(argv[i]); + } + + bool ok; + + NPVariant result; + if (identifier) { + ok = WebBindings::invoke(NULL, object, identifier, args.get(), argc, + &result); + } else { + ok = WebBindings::invokeDefault(NULL, object, args.get(), argc, &result); + } + + if (!ok) { + // TODO(darin): raise exception + return PP_MakeVoid(); + } + + PP_Var ret = NPVariantToPPVar(&result); + WebBindings::releaseVariantValue(&result); return ret; } -PP_Var Construct(PP_Var object, +PP_Var Construct(PP_Var var, int32_t argc, PP_Var* argv, PP_Var* exception) { - // TODO(brettw) implement this. - PP_Var ret; - ret.type = PP_VarType_Void; + if (exception && exception->type != PP_VarType_Void) + return PP_MakeVoid(); + + NPObject* object = GetNPObject(var); + if (!object) { + // TODO(darin): raise exception + return PP_MakeVoid(); + } + + scoped_array<NPVariant> args; + if (argc) { + args.reset(new NPVariant[argc]); + for (int32_t i = 0; i < argc; ++i) + args[i] = PPVarToNPVariantNoCopy(argv[i]); + } + + NPVariant result; + if (!WebBindings::construct(NULL, object, args.get(), argc, &result)) { + // TODO(darin): raise exception + return PP_MakeVoid(); + } + + PP_Var ret = NPVariantToPPVar(&result); + WebBindings::releaseVariantValue(&result); return ret; } PP_Var CreateObject(const PPP_Class* object_class, void* object_data) { - // TODO(brettw) implement this. - PP_Var ret; - ret.type = PP_VarType_Void; - return ret; + return PP_MakeVoid(); // TODO(darin) } const PPB_Var var_interface = { @@ -135,4 +284,109 @@ const PPB_Var* GetVarInterface() { return &var_interface; } +PP_Var NPObjectToPPVar(NPObject* object) { + PP_Var ret; + ret.type = PP_VarType_Object; + ret.value.as_id = reinterpret_cast<intptr_t>(object); + WebBindings::retainObject(object); + return ret; +} + +PP_Var NPVariantToPPVar(NPVariant* variant) { + switch (variant->type) { + case NPVariantType_Void: + return PP_MakeVoid(); + case NPVariantType_Null: + return PP_MakeNull(); + case NPVariantType_Bool: + return PP_MakeBool(NPVARIANT_TO_BOOLEAN(*variant)); + case NPVariantType_Int32: + return PP_MakeInt32(NPVARIANT_TO_INT32(*variant)); + case NPVariantType_Double: + return PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant)); + case NPVariantType_String: + return VarFromUtf8(NPVARIANT_TO_STRING(*variant).UTF8Characters, + NPVARIANT_TO_STRING(*variant).UTF8Length); + case NPVariantType_Object: + return NPObjectToPPVar(NPVARIANT_TO_OBJECT(*variant)); + } + NOTREACHED(); + return PP_MakeVoid(); +} + +NPVariant PPVarToNPVariant(PP_Var var) { + NPVariant ret; + switch (var.type) { + case PP_VarType_Void: + VOID_TO_NPVARIANT(ret); + break; + case PP_VarType_Null: + NULL_TO_NPVARIANT(ret); + break; + case PP_VarType_Bool: + BOOLEAN_TO_NPVARIANT(var.value.as_bool, ret); + break; + case PP_VarType_Int32: + INT32_TO_NPVARIANT(var.value.as_int, ret); + break; + case PP_VarType_Double: + DOUBLE_TO_NPVARIANT(var.value.as_double, ret); + break; + case PP_VarType_String: { + const std::string& value = GetStringUnchecked(var)->value(); + STRINGN_TO_NPVARIANT(base::strdup(value.c_str()), value.size(), ret); + break; + } + case PP_VarType_Object: { + NPObject* object = GetNPObjectUnchecked(var); + OBJECT_TO_NPVARIANT(WebBindings::retainObject(object), ret); + break; + } + } + return ret; +} + +NPVariant PPVarToNPVariantNoCopy(PP_Var var) { + NPVariant ret; + switch (var.type) { + case PP_VarType_Void: + VOID_TO_NPVARIANT(ret); + break; + case PP_VarType_Null: + NULL_TO_NPVARIANT(ret); + break; + case PP_VarType_Bool: + BOOLEAN_TO_NPVARIANT(var.value.as_bool, ret); + break; + case PP_VarType_Int32: + INT32_TO_NPVARIANT(var.value.as_int, ret); + break; + case PP_VarType_Double: + DOUBLE_TO_NPVARIANT(var.value.as_double, ret); + break; + case PP_VarType_String: { + const std::string& value = GetStringUnchecked(var)->value(); + STRINGN_TO_NPVARIANT(value.c_str(), value.size(), ret); + break; + } + case PP_VarType_Object: { + OBJECT_TO_NPVARIANT(GetNPObjectUnchecked(var), ret); + break; + } + } + return ret; +} + +NPIdentifier PPVarToNPIdentifier(PP_Var var) { + switch (var.type) { + case PP_VarType_String: + return WebBindings::getStringIdentifier( + GetStringUnchecked(var)->value().c_str()); + case PP_VarType_Int32: + return WebBindings::getIntIdentifier(var.value.as_int); + default: + return NULL; + } +} + } // namespace pepper diff --git a/webkit/glue/plugins/pepper_var.h b/webkit/glue/plugins/pepper_var.h index c9d29fe..6c8c6b5 100644 --- a/webkit/glue/plugins/pepper_var.h +++ b/webkit/glue/plugins/pepper_var.h @@ -5,7 +5,11 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_VAR_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_VAR_H_ +typedef struct _pp_Var PP_Var; typedef struct _ppb_Var PPB_Var; +typedef struct NPObject NPObject; +typedef struct _NPVariant NPVariant; +typedef void* NPIdentifier; namespace pepper { @@ -14,6 +18,28 @@ namespace pepper { // the .cc file here. const PPB_Var* GetVarInterface(); +// Returns a PP_Var of type object that wraps the given NPObject. Calling this +// function multiple times given the same NPObject results in the same PP_Var. +PP_Var NPObjectToPPVar(NPObject* object); + +// Returns a PP_Var that corresponds to the given NPVariant. The contents of +// the NPVariant will be copied unless the NPVariant corresponds to an object. +PP_Var NPVariantToPPVar(NPVariant* variant); + +// Returns a NPVariant that corresponds to the given PP_Var. The contents of +// the PP_Var will be copied unless the PP_Var corresponds to an object. +NPVariant PPVarToNPVariant(PP_Var var); + +// Returns a NPVariant that corresponds to the given PP_Var. The contents of +// the PP_Var will NOT be copied, so you need to ensure that the PP_Var remains +// valid while the resultant NPVariant is in use. +NPVariant PPVarToNPVariantNoCopy(PP_Var var); + +// Returns a NPIdentifier that corresponds to the given PP_Var. The contents +// of the PP_Var will be copied. Returns NULL if the given PP_Var is not a a +// string or integer type. +NPIdentifier PPVarToNPIdentifier(PP_Var var); + } // namespace pepper #endif // WEBKIT_GLUE_PLUGINS_PEPPER_VAR_H_ diff --git a/webkit/glue/plugins/pepper_webplugin_impl.cc b/webkit/glue/plugins/pepper_webplugin_impl.cc index cc44cfe..de83339 100644 --- a/webkit/glue/plugins/pepper_webplugin_impl.cc +++ b/webkit/glue/plugins/pepper_webplugin_impl.cc @@ -24,8 +24,7 @@ WebPluginImpl::WebPluginImpl( WebKit::WebFrame* frame, const WebPluginParams& params, const base::WeakPtr<PluginDelegate>& plugin_delegate) - : init_data_(new InitData()), - container_(NULL) { + : init_data_(new InitData()) { DCHECK(plugin_module); init_data_->module = plugin_module; init_data_->delegate = plugin_delegate; @@ -47,7 +46,8 @@ bool WebPluginImpl::initialize(WebPluginContainer* container) { if (!instance_) return false; - bool success = instance_->Initialize(init_data_->arg_names, + bool success = instance_->Initialize(container, + init_data_->arg_names, init_data_->arg_values); if (!success) { instance_->Delete(); @@ -56,13 +56,10 @@ bool WebPluginImpl::initialize(WebPluginContainer* container) { } init_data_.reset(); - container_ = container; return true; } void WebPluginImpl::destroy() { - container_ = NULL; - if (instance_) { instance_->Delete(); instance_ = NULL; diff --git a/webkit/glue/plugins/pepper_webplugin_impl.h b/webkit/glue/plugins/pepper_webplugin_impl.h index 03e4145..e8ce265 100644 --- a/webkit/glue/plugins/pepper_webplugin_impl.h +++ b/webkit/glue/plugins/pepper_webplugin_impl.h @@ -10,6 +10,7 @@ #include "base/weak_ptr.h" #include "base/scoped_ptr.h" +#include "base/task.h" #include "gfx/rect.h" #include "third_party/WebKit/WebKit/chromium/public/WebPlugin.h" @@ -30,6 +31,10 @@ class WebPluginImpl : public WebKit::WebPlugin { WebKit::WebFrame* frame, const WebKit::WebPluginParams& params, const base::WeakPtr<PluginDelegate>& plugin_delegate); + + private: + friend class DeleteTask<WebPluginImpl>; + ~WebPluginImpl(); // WebKit::WebPlugin implementation. @@ -57,7 +62,6 @@ class WebPluginImpl : public WebKit::WebPlugin { void* notify_data, const WebKit::WebURLError& error); - public: struct InitData { scoped_refptr<PluginModule> module; base::WeakPtr<PluginDelegate> delegate; @@ -67,7 +71,6 @@ class WebPluginImpl : public WebKit::WebPlugin { scoped_ptr<InitData> init_data_; // Cleared upon successful initialization. scoped_refptr<PluginInstance> instance_; - WebKit::WebPluginContainer* container_; // Can be NULL. gfx::Rect plugin_rect_; DISALLOW_COPY_AND_ASSIGN(WebPluginImpl); |