Home | History | Annotate | Download | only in cpp
      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