// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ppapi/cpp/instance.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/ppb_console.h" #include "ppapi/c/ppb_input_event.h" #include "ppapi/c/ppb_instance.h" #include "ppapi/c/ppb_messaging.h" #include "ppapi/c/ppp_message_handler.h" #include "ppapi/cpp/compositor.h" #include "ppapi/cpp/graphics_2d.h" #include "ppapi/cpp/graphics_3d.h" #include "ppapi/cpp/image_data.h" #include "ppapi/cpp/instance_handle.h" #include "ppapi/cpp/logging.h" #include "ppapi/cpp/message_handler.h" #include "ppapi/cpp/message_loop.h" #include "ppapi/cpp/module.h" #include "ppapi/cpp/module_impl.h" #include "ppapi/cpp/point.h" #include "ppapi/cpp/resource.h" #include "ppapi/cpp/var.h" #include "ppapi/cpp/view.h" namespace pp { namespace { template <> const char* interface_name() { return PPB_CONSOLE_INTERFACE_1_0; } template <> const char* interface_name() { return PPB_INPUT_EVENT_INTERFACE_1_0; } template <> const char* interface_name() { return PPB_INSTANCE_INTERFACE_1_0; } template <> const char* interface_name() { return PPB_MESSAGING_INTERFACE_1_0; } template <> const char* interface_name() { return PPB_MESSAGING_INTERFACE_1_2; } // PPP_MessageHandler implementation ------------------------------------------- void HandleMessage(PP_Instance pp_instance, void* user_data, const PP_Var* var) { MessageHandler* message_handler = static_cast(user_data); message_handler->HandleMessage(InstanceHandle(pp_instance), Var(*var)); } void HandleBlockingMessage(PP_Instance pp_instance, void* user_data, const PP_Var* var, PP_Var* result) { MessageHandler* message_handler = static_cast(user_data); pp::Var result_var = message_handler->HandleBlockingMessage(InstanceHandle(pp_instance), Var(*var)); *result = result_var.Detach(); } void Destroy(PP_Instance pp_instance, void* user_data) { MessageHandler* message_handler = static_cast(user_data); message_handler->WasUnregistered(InstanceHandle(pp_instance)); } static PPP_MessageHandler_0_2 message_handler_if = { &HandleMessage, &HandleBlockingMessage, &Destroy }; } // namespace Instance::Instance(PP_Instance instance) : pp_instance_(instance) { } Instance::~Instance() { } bool Instance::Init(uint32_t /*argc*/, const char* /*argn*/[], const char* /*argv*/[]) { return true; } void Instance::DidChangeView(const View& view) { // Call the deprecated version for source backwards-compat. DidChangeView(view.GetRect(), view.GetClipRect()); } void Instance::DidChangeView(const pp::Rect& /*position*/, const pp::Rect& /*clip*/) { } void Instance::DidChangeFocus(bool /*has_focus*/) { } bool Instance::HandleDocumentLoad(const URLLoader& /*url_loader*/) { return false; } bool Instance::HandleInputEvent(const InputEvent& /*event*/) { return false; } void Instance::HandleMessage(const Var& /*message*/) { return; } bool Instance::BindGraphics(const Graphics2D& graphics) { if (!has_interface()) return false; return PP_ToBool(get_interface()->BindGraphics( pp_instance(), graphics.pp_resource())); } bool Instance::BindGraphics(const Graphics3D& graphics) { if (!has_interface()) return false; return PP_ToBool(get_interface()->BindGraphics( pp_instance(), graphics.pp_resource())); } bool Instance::BindGraphics(const Compositor& compositor) { if (!has_interface()) return false; return PP_ToBool(get_interface()->BindGraphics( pp_instance(), compositor.pp_resource())); } bool Instance::IsFullFrame() { if (!has_interface()) return false; return PP_ToBool(get_interface()->IsFullFrame( pp_instance())); } int32_t Instance::RequestInputEvents(uint32_t event_classes) { if (!has_interface()) return PP_ERROR_NOINTERFACE; return get_interface()->RequestInputEvents(pp_instance(), event_classes); } int32_t Instance::RequestFilteringInputEvents(uint32_t event_classes) { if (!has_interface()) return PP_ERROR_NOINTERFACE; return get_interface()->RequestFilteringInputEvents( pp_instance(), event_classes); } void Instance::ClearInputEventRequest(uint32_t event_classes) { if (!has_interface()) return; get_interface()->ClearInputEventRequest(pp_instance(), event_classes); } void Instance::PostMessage(const Var& message) { if (has_interface()) { get_interface()->PostMessage(pp_instance(), message.pp_var()); } else if (has_interface()) { get_interface()->PostMessage(pp_instance(), message.pp_var()); } } int32_t Instance::RegisterMessageHandler(MessageHandler* message_handler, const MessageLoop& message_loop) { if (!has_interface()) return PP_ERROR_NOTSUPPORTED; return get_interface()->RegisterMessageHandler( pp_instance(), message_handler, &message_handler_if, message_loop.pp_resource()); } void Instance::UnregisterMessageHandler() { if (!has_interface()) return; get_interface()->UnregisterMessageHandler(pp_instance()); } void Instance::LogToConsole(PP_LogLevel level, const Var& value) { if (!has_interface()) return; get_interface()->Log( pp_instance(), level, value.pp_var()); } void Instance::LogToConsoleWithSource(PP_LogLevel level, const Var& source, const Var& value) { if (!has_interface()) return; get_interface()->LogWithSource( pp_instance(), level, source.pp_var(), value.pp_var()); } void Instance::AddPerInstanceObject(const std::string& interface_name, void* object) { // Ensure we're not trying to register more than one object per interface // type. Otherwise, we'll get confused in GetPerInstanceObject. PP_DCHECK(interface_name_to_objects_.find(interface_name) == interface_name_to_objects_.end()); interface_name_to_objects_[interface_name] = object; } void Instance::RemovePerInstanceObject(const std::string& interface_name, void* object) { InterfaceNameToObjectMap::iterator found = interface_name_to_objects_.find( interface_name); if (found == interface_name_to_objects_.end()) { // Attempting to unregister an object that doesn't exist or was already // unregistered. PP_DCHECK(false); return; } // Validate that we're removing the object we thing we are. PP_DCHECK(found->second == object); (void)object; // Prevent warning in release mode. interface_name_to_objects_.erase(found); } // static void Instance::RemovePerInstanceObject(const InstanceHandle& instance, const std::string& interface_name, void* object) { // TODO(brettw) assert we're on the main thread. Instance* that = Module::Get()->InstanceForPPInstance(instance.pp_instance()); if (!that) return; that->RemovePerInstanceObject(interface_name, object); } // static void* Instance::GetPerInstanceObject(PP_Instance instance, const std::string& interface_name) { Instance* that = Module::Get()->InstanceForPPInstance(instance); if (!that) return NULL; InterfaceNameToObjectMap::iterator found = that->interface_name_to_objects_.find(interface_name); if (found == that->interface_name_to_objects_.end()) return NULL; return found->second; } } // namespace pp