1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ppapi/cpp/instance.h" 6 7 #include "ppapi/c/pp_errors.h" 8 #include "ppapi/c/ppb_console.h" 9 #include "ppapi/c/ppb_input_event.h" 10 #include "ppapi/c/ppb_instance.h" 11 #include "ppapi/c/ppb_messaging.h" 12 #include "ppapi/c/ppp_message_handler.h" 13 #include "ppapi/cpp/compositor.h" 14 #include "ppapi/cpp/graphics_2d.h" 15 #include "ppapi/cpp/graphics_3d.h" 16 #include "ppapi/cpp/image_data.h" 17 #include "ppapi/cpp/instance_handle.h" 18 #include "ppapi/cpp/logging.h" 19 #include "ppapi/cpp/message_handler.h" 20 #include "ppapi/cpp/message_loop.h" 21 #include "ppapi/cpp/module.h" 22 #include "ppapi/cpp/module_impl.h" 23 #include "ppapi/cpp/point.h" 24 #include "ppapi/cpp/resource.h" 25 #include "ppapi/cpp/var.h" 26 #include "ppapi/cpp/view.h" 27 28 namespace pp { 29 30 namespace { 31 32 template <> const char* interface_name<PPB_Console_1_0>() { 33 return PPB_CONSOLE_INTERFACE_1_0; 34 } 35 36 template <> const char* interface_name<PPB_InputEvent_1_0>() { 37 return PPB_INPUT_EVENT_INTERFACE_1_0; 38 } 39 40 template <> const char* interface_name<PPB_Instance_1_0>() { 41 return PPB_INSTANCE_INTERFACE_1_0; 42 } 43 44 template <> const char* interface_name<PPB_Messaging_1_0>() { 45 return PPB_MESSAGING_INTERFACE_1_0; 46 } 47 48 template <> const char* interface_name<PPB_Messaging_1_2>() { 49 return PPB_MESSAGING_INTERFACE_1_2; 50 } 51 52 // PPP_MessageHandler implementation ------------------------------------------- 53 void HandleMessage(PP_Instance pp_instance, 54 void* user_data, 55 const PP_Var* var) { 56 MessageHandler* message_handler = static_cast<MessageHandler*>(user_data); 57 message_handler->HandleMessage(InstanceHandle(pp_instance), Var(*var)); 58 } 59 60 void HandleBlockingMessage(PP_Instance pp_instance, 61 void* user_data, 62 const PP_Var* var, 63 PP_Var* result) { 64 MessageHandler* message_handler = static_cast<MessageHandler*>(user_data); 65 pp::Var result_var = 66 message_handler->HandleBlockingMessage(InstanceHandle(pp_instance), 67 Var(*var)); 68 *result = result_var.Detach(); 69 } 70 71 void Destroy(PP_Instance pp_instance, void* user_data) { 72 MessageHandler* message_handler = static_cast<MessageHandler*>(user_data); 73 message_handler->WasUnregistered(InstanceHandle(pp_instance)); 74 } 75 76 static PPP_MessageHandler_0_2 message_handler_if = { 77 &HandleMessage, &HandleBlockingMessage, &Destroy 78 }; 79 80 } // namespace 81 82 Instance::Instance(PP_Instance instance) : pp_instance_(instance) { 83 } 84 85 Instance::~Instance() { 86 } 87 88 bool Instance::Init(uint32_t /*argc*/, const char* /*argn*/[], 89 const char* /*argv*/[]) { 90 return true; 91 } 92 93 void Instance::DidChangeView(const View& view) { 94 // Call the deprecated version for source backwards-compat. 95 DidChangeView(view.GetRect(), view.GetClipRect()); 96 } 97 98 void Instance::DidChangeView(const pp::Rect& /*position*/, 99 const pp::Rect& /*clip*/) { 100 } 101 102 void Instance::DidChangeFocus(bool /*has_focus*/) { 103 } 104 105 106 bool Instance::HandleDocumentLoad(const URLLoader& /*url_loader*/) { 107 return false; 108 } 109 110 bool Instance::HandleInputEvent(const InputEvent& /*event*/) { 111 return false; 112 } 113 114 void Instance::HandleMessage(const Var& /*message*/) { 115 return; 116 } 117 118 bool Instance::BindGraphics(const Graphics2D& graphics) { 119 if (!has_interface<PPB_Instance_1_0>()) 120 return false; 121 return PP_ToBool(get_interface<PPB_Instance_1_0>()->BindGraphics( 122 pp_instance(), graphics.pp_resource())); 123 } 124 125 bool Instance::BindGraphics(const Graphics3D& graphics) { 126 if (!has_interface<PPB_Instance_1_0>()) 127 return false; 128 return PP_ToBool(get_interface<PPB_Instance_1_0>()->BindGraphics( 129 pp_instance(), graphics.pp_resource())); 130 } 131 132 bool Instance::BindGraphics(const Compositor& compositor) { 133 if (!has_interface<PPB_Instance_1_0>()) 134 return false; 135 return PP_ToBool(get_interface<PPB_Instance_1_0>()->BindGraphics( 136 pp_instance(), compositor.pp_resource())); 137 } 138 139 bool Instance::IsFullFrame() { 140 if (!has_interface<PPB_Instance_1_0>()) 141 return false; 142 return PP_ToBool(get_interface<PPB_Instance_1_0>()->IsFullFrame( 143 pp_instance())); 144 } 145 146 int32_t Instance::RequestInputEvents(uint32_t event_classes) { 147 if (!has_interface<PPB_InputEvent_1_0>()) 148 return PP_ERROR_NOINTERFACE; 149 return get_interface<PPB_InputEvent_1_0>()->RequestInputEvents(pp_instance(), 150 event_classes); 151 } 152 153 int32_t Instance::RequestFilteringInputEvents(uint32_t event_classes) { 154 if (!has_interface<PPB_InputEvent_1_0>()) 155 return PP_ERROR_NOINTERFACE; 156 return get_interface<PPB_InputEvent_1_0>()->RequestFilteringInputEvents( 157 pp_instance(), event_classes); 158 } 159 160 void Instance::ClearInputEventRequest(uint32_t event_classes) { 161 if (!has_interface<PPB_InputEvent_1_0>()) 162 return; 163 get_interface<PPB_InputEvent_1_0>()->ClearInputEventRequest(pp_instance(), 164 event_classes); 165 } 166 167 void Instance::PostMessage(const Var& message) { 168 if (has_interface<PPB_Messaging_1_2>()) { 169 get_interface<PPB_Messaging_1_2>()->PostMessage(pp_instance(), 170 message.pp_var()); 171 } else if (has_interface<PPB_Messaging_1_0>()) { 172 get_interface<PPB_Messaging_1_0>()->PostMessage(pp_instance(), 173 message.pp_var()); 174 } 175 } 176 177 int32_t Instance::RegisterMessageHandler(MessageHandler* message_handler, 178 const MessageLoop& message_loop) { 179 if (!has_interface<PPB_Messaging_1_2>()) 180 return PP_ERROR_NOTSUPPORTED; 181 return get_interface<PPB_Messaging_1_2>()->RegisterMessageHandler( 182 pp_instance(), 183 message_handler, 184 &message_handler_if, 185 message_loop.pp_resource()); 186 } 187 188 void Instance::UnregisterMessageHandler() { 189 if (!has_interface<PPB_Messaging_1_2>()) 190 return; 191 get_interface<PPB_Messaging_1_2>()->UnregisterMessageHandler(pp_instance()); 192 } 193 194 void Instance::LogToConsole(PP_LogLevel level, const Var& value) { 195 if (!has_interface<PPB_Console_1_0>()) 196 return; 197 get_interface<PPB_Console_1_0>()->Log( 198 pp_instance(), level, value.pp_var()); 199 } 200 201 void Instance::LogToConsoleWithSource(PP_LogLevel level, 202 const Var& source, 203 const Var& value) { 204 if (!has_interface<PPB_Console_1_0>()) 205 return; 206 get_interface<PPB_Console_1_0>()->LogWithSource( 207 pp_instance(), level, source.pp_var(), value.pp_var()); 208 } 209 210 void Instance::AddPerInstanceObject(const std::string& interface_name, 211 void* object) { 212 // Ensure we're not trying to register more than one object per interface 213 // type. Otherwise, we'll get confused in GetPerInstanceObject. 214 PP_DCHECK(interface_name_to_objects_.find(interface_name) == 215 interface_name_to_objects_.end()); 216 interface_name_to_objects_[interface_name] = object; 217 } 218 219 void Instance::RemovePerInstanceObject(const std::string& interface_name, 220 void* object) { 221 InterfaceNameToObjectMap::iterator found = interface_name_to_objects_.find( 222 interface_name); 223 if (found == interface_name_to_objects_.end()) { 224 // Attempting to unregister an object that doesn't exist or was already 225 // unregistered. 226 PP_DCHECK(false); 227 return; 228 } 229 230 // Validate that we're removing the object we thing we are. 231 PP_DCHECK(found->second == object); 232 (void)object; // Prevent warning in release mode. 233 234 interface_name_to_objects_.erase(found); 235 } 236 237 // static 238 void Instance::RemovePerInstanceObject(const InstanceHandle& instance, 239 const std::string& interface_name, 240 void* object) { 241 // TODO(brettw) assert we're on the main thread. 242 Instance* that = Module::Get()->InstanceForPPInstance(instance.pp_instance()); 243 if (!that) 244 return; 245 that->RemovePerInstanceObject(interface_name, object); 246 } 247 248 // static 249 void* Instance::GetPerInstanceObject(PP_Instance instance, 250 const std::string& interface_name) { 251 Instance* that = Module::Get()->InstanceForPPInstance(instance); 252 if (!that) 253 return NULL; 254 InterfaceNameToObjectMap::iterator found = 255 that->interface_name_to_objects_.find(interface_name); 256 if (found == that->interface_name_to_objects_.end()) 257 return NULL; 258 return found->second; 259 } 260 261 } // namespace pp 262