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/cpp/compositor.h"
13#include "ppapi/cpp/graphics_2d.h"
14#include "ppapi/cpp/graphics_3d.h"
15#include "ppapi/cpp/image_data.h"
16#include "ppapi/cpp/instance_handle.h"
17#include "ppapi/cpp/logging.h"
18#include "ppapi/cpp/module.h"
19#include "ppapi/cpp/module_impl.h"
20#include "ppapi/cpp/point.h"
21#include "ppapi/cpp/resource.h"
22#include "ppapi/cpp/var.h"
23#include "ppapi/cpp/view.h"
24
25namespace pp {
26
27namespace {
28
29template <> const char* interface_name<PPB_Console_1_0>() {
30  return PPB_CONSOLE_INTERFACE_1_0;
31}
32
33template <> const char* interface_name<PPB_InputEvent_1_0>() {
34  return PPB_INPUT_EVENT_INTERFACE_1_0;
35}
36
37template <> const char* interface_name<PPB_Instance_1_0>() {
38  return PPB_INSTANCE_INTERFACE_1_0;
39}
40
41template <> const char* interface_name<PPB_Messaging_1_0>() {
42  return PPB_MESSAGING_INTERFACE_1_0;
43}
44
45}  // namespace
46
47Instance::Instance(PP_Instance instance) : pp_instance_(instance) {
48}
49
50Instance::~Instance() {
51}
52
53bool Instance::Init(uint32_t /*argc*/, const char* /*argn*/[],
54                    const char* /*argv*/[]) {
55  return true;
56}
57
58void Instance::DidChangeView(const View& view) {
59  // Call the deprecated version for source backwards-compat.
60  DidChangeView(view.GetRect(), view.GetClipRect());
61}
62
63void Instance::DidChangeView(const pp::Rect& /*position*/,
64                             const pp::Rect& /*clip*/) {
65}
66
67void Instance::DidChangeFocus(bool /*has_focus*/) {
68}
69
70
71bool Instance::HandleDocumentLoad(const URLLoader& /*url_loader*/) {
72  return false;
73}
74
75bool Instance::HandleInputEvent(const InputEvent& /*event*/) {
76  return false;
77}
78
79void Instance::HandleMessage(const Var& /*message*/) {
80  return;
81}
82
83bool Instance::BindGraphics(const Graphics2D& graphics) {
84  if (!has_interface<PPB_Instance_1_0>())
85    return false;
86  return PP_ToBool(get_interface<PPB_Instance_1_0>()->BindGraphics(
87      pp_instance(), graphics.pp_resource()));
88}
89
90bool Instance::BindGraphics(const Graphics3D& graphics) {
91  if (!has_interface<PPB_Instance_1_0>())
92    return false;
93  return PP_ToBool(get_interface<PPB_Instance_1_0>()->BindGraphics(
94      pp_instance(), graphics.pp_resource()));
95}
96
97bool Instance::BindGraphics(const Compositor& compositor) {
98  if (!has_interface<PPB_Instance_1_0>())
99    return false;
100  return PP_ToBool(get_interface<PPB_Instance_1_0>()->BindGraphics(
101      pp_instance(), compositor.pp_resource()));
102}
103
104bool Instance::IsFullFrame() {
105  if (!has_interface<PPB_Instance_1_0>())
106    return false;
107  return PP_ToBool(get_interface<PPB_Instance_1_0>()->IsFullFrame(
108      pp_instance()));
109}
110
111int32_t Instance::RequestInputEvents(uint32_t event_classes) {
112  if (!has_interface<PPB_InputEvent_1_0>())
113    return PP_ERROR_NOINTERFACE;
114  return get_interface<PPB_InputEvent_1_0>()->RequestInputEvents(pp_instance(),
115                                                                 event_classes);
116}
117
118int32_t Instance::RequestFilteringInputEvents(uint32_t event_classes) {
119  if (!has_interface<PPB_InputEvent_1_0>())
120    return PP_ERROR_NOINTERFACE;
121  return get_interface<PPB_InputEvent_1_0>()->RequestFilteringInputEvents(
122      pp_instance(), event_classes);
123}
124
125void Instance::ClearInputEventRequest(uint32_t event_classes) {
126  if (!has_interface<PPB_InputEvent_1_0>())
127    return;
128  get_interface<PPB_InputEvent_1_0>()->ClearInputEventRequest(pp_instance(),
129                                                          event_classes);
130}
131
132void Instance::PostMessage(const Var& message) {
133  if (!has_interface<PPB_Messaging_1_0>())
134    return;
135  get_interface<PPB_Messaging_1_0>()->PostMessage(pp_instance(),
136                                              message.pp_var());
137}
138
139void Instance::LogToConsole(PP_LogLevel level, const Var& value) {
140  if (!has_interface<PPB_Console_1_0>())
141    return;
142  get_interface<PPB_Console_1_0>()->Log(
143      pp_instance(), level, value.pp_var());
144}
145
146void Instance::LogToConsoleWithSource(PP_LogLevel level,
147                                      const Var& source,
148                                      const Var& value) {
149  if (!has_interface<PPB_Console_1_0>())
150    return;
151  get_interface<PPB_Console_1_0>()->LogWithSource(
152      pp_instance(), level, source.pp_var(), value.pp_var());
153}
154
155void Instance::AddPerInstanceObject(const std::string& interface_name,
156                                    void* object) {
157  // Ensure we're not trying to register more than one object per interface
158  // type. Otherwise, we'll get confused in GetPerInstanceObject.
159  PP_DCHECK(interface_name_to_objects_.find(interface_name) ==
160            interface_name_to_objects_.end());
161  interface_name_to_objects_[interface_name] = object;
162}
163
164void Instance::RemovePerInstanceObject(const std::string& interface_name,
165                                       void* object) {
166  InterfaceNameToObjectMap::iterator found = interface_name_to_objects_.find(
167      interface_name);
168  if (found == interface_name_to_objects_.end()) {
169    // Attempting to unregister an object that doesn't exist or was already
170    // unregistered.
171    PP_DCHECK(false);
172    return;
173  }
174
175  // Validate that we're removing the object we thing we are.
176  PP_DCHECK(found->second == object);
177  (void)object;  // Prevent warning in release mode.
178
179  interface_name_to_objects_.erase(found);
180}
181
182// static
183void Instance::RemovePerInstanceObject(const InstanceHandle& instance,
184                                       const std::string& interface_name,
185                                       void* object) {
186  // TODO(brettw) assert we're on the main thread.
187  Instance* that = Module::Get()->InstanceForPPInstance(instance.pp_instance());
188  if (!that)
189    return;
190  that->RemovePerInstanceObject(interface_name, object);
191}
192
193// static
194void* Instance::GetPerInstanceObject(PP_Instance instance,
195                                     const std::string& interface_name) {
196  Instance* that = Module::Get()->InstanceForPPInstance(instance);
197  if (!that)
198    return NULL;
199  InterfaceNameToObjectMap::iterator found =
200      that->interface_name_to_objects_.find(interface_name);
201  if (found == that->interface_name_to_objects_.end())
202    return NULL;
203  return found->second;
204}
205
206}  // namespace pp
207