summaryrefslogtreecommitdiffstats
path: root/ppapi/cpp
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-01 16:16:50 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-01 16:16:50 +0000
commit1758e88fd909ea0ffd49621e8066ffad5627ffdf (patch)
treec304a5eed047cae5665f5af1739d84655fb5815d /ppapi/cpp
parente7d8b51953b7d3b2b8a0aba46132305b32f3efce (diff)
downloadchromium_src-1758e88fd909ea0ffd49621e8066ffad5627ffdf.zip
chromium_src-1758e88fd909ea0ffd49621e8066ffad5627ffdf.tar.gz
chromium_src-1758e88fd909ea0ffd49621e8066ffad5627ffdf.tar.bz2
Move PPAPI into the Chrome repo. The old repo was
http://ppapi.googlecode.com/ TEST=none BUG=none git-svn-id: svn://svn.chromium.org/chrome/trunk/src@64613 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/cpp')
-rw-r--r--ppapi/cpp/completion_callback.h313
-rw-r--r--ppapi/cpp/core.cc25
-rw-r--r--ppapi/cpp/core.h67
-rw-r--r--ppapi/cpp/dev/audio_config_dev.cc39
-rw-r--r--ppapi/cpp/dev/audio_config_dev.h57
-rw-r--r--ppapi/cpp/dev/audio_dev.cc38
-rw-r--r--ppapi/cpp/dev/audio_dev.h38
-rw-r--r--ppapi/cpp/dev/buffer_dev.cc55
-rw-r--r--ppapi/cpp/dev/buffer_dev.h39
-rw-r--r--ppapi/cpp/dev/directory_entry_dev.cc41
-rw-r--r--ppapi/cpp/dev/directory_entry_dev.h38
-rw-r--r--ppapi/cpp/dev/directory_reader_dev.cc53
-rw-r--r--ppapi/cpp/dev/directory_reader_dev.h36
-rw-r--r--ppapi/cpp/dev/file_chooser_dev.cc58
-rw-r--r--ppapi/cpp/dev/file_chooser_dev.h38
-rw-r--r--ppapi/cpp/dev/file_io_dev.cc135
-rw-r--r--ppapi/cpp/dev/file_io_dev.h61
-rw-r--r--ppapi/cpp/dev/file_ref_dev.cc124
-rw-r--r--ppapi/cpp/dev/file_ref_dev.h71
-rw-r--r--ppapi/cpp/dev/file_system_dev.cc37
-rw-r--r--ppapi/cpp/dev/file_system_dev.h32
-rw-r--r--ppapi/cpp/dev/find_dev.cc75
-rw-r--r--ppapi/cpp/dev/find_dev.h61
-rw-r--r--ppapi/cpp/dev/font_dev.cc210
-rw-r--r--ppapi/cpp/dev/font_dev.h139
-rw-r--r--ppapi/cpp/dev/fullscreen_dev.cc39
-rw-r--r--ppapi/cpp/dev/fullscreen_dev.h31
-rw-r--r--ppapi/cpp/dev/graphics_3d_client_dev.cc43
-rw-r--r--ppapi/cpp/dev/graphics_3d_client_dev.h36
-rw-r--r--ppapi/cpp/dev/graphics_3d_dev.cc117
-rw-r--r--ppapi/cpp/dev/graphics_3d_dev.h54
-rw-r--r--ppapi/cpp/dev/printing_dev.cc74
-rw-r--r--ppapi/cpp/dev/printing_dev.h38
-rw-r--r--ppapi/cpp/dev/scriptable_object_deprecated.cc188
-rw-r--r--ppapi/cpp/dev/scriptable_object_deprecated.h92
-rw-r--r--ppapi/cpp/dev/scrollbar_dev.cc84
-rw-r--r--ppapi/cpp/dev/scrollbar_dev.h39
-rw-r--r--ppapi/cpp/dev/selection_dev.cc41
-rw-r--r--ppapi/cpp/dev/selection_dev.h52
-rw-r--r--ppapi/cpp/dev/transport_dev.cc28
-rw-r--r--ppapi/cpp/dev/transport_dev.h23
-rw-r--r--ppapi/cpp/dev/url_loader_dev.cc115
-rw-r--r--ppapi/cpp/dev/url_loader_dev.h108
-rw-r--r--ppapi/cpp/dev/url_request_info_dev.cc81
-rw-r--r--ppapi/cpp/dev/url_request_info_dev.h57
-rw-r--r--ppapi/cpp/dev/url_response_info_dev.cc54
-rw-r--r--ppapi/cpp/dev/url_response_info_dev.h58
-rw-r--r--ppapi/cpp/dev/url_util_dev.cc70
-rw-r--r--ppapi/cpp/dev/url_util_dev.h54
-rw-r--r--ppapi/cpp/dev/video_decoder_dev.cc84
-rw-r--r--ppapi/cpp/dev/video_decoder_dev.h47
-rw-r--r--ppapi/cpp/dev/widget_client_dev.cc74
-rw-r--r--ppapi/cpp/dev/widget_client_dev.h44
-rw-r--r--ppapi/cpp/dev/widget_dev.cc62
-rw-r--r--ppapi/cpp/dev/widget_dev.h41
-rw-r--r--ppapi/cpp/dev/zoom_dev.cc58
-rw-r--r--ppapi/cpp/dev/zoom_dev.h58
-rw-r--r--ppapi/cpp/graphics_2d.cc98
-rw-r--r--ppapi/cpp/graphics_2d.h75
-rw-r--r--ppapi/cpp/image_data.cc98
-rw-r--r--ppapi/cpp/image_data.h65
-rw-r--r--ppapi/cpp/instance.cc143
-rw-r--r--ppapi/cpp/instance.h157
-rw-r--r--ppapi/cpp/logging.h14
-rw-r--r--ppapi/cpp/module.cc198
-rw-r--r--ppapi/cpp/module.h123
-rw-r--r--ppapi/cpp/module_embedder.h20
-rw-r--r--ppapi/cpp/module_impl.h41
-rw-r--r--ppapi/cpp/non_thread_safe_ref_count.h48
-rw-r--r--ppapi/cpp/paint_aggregator.cc274
-rw-r--r--ppapi/cpp/paint_aggregator.h130
-rw-r--r--ppapi/cpp/paint_manager.cc174
-rw-r--r--ppapi/cpp/paint_manager.h207
-rw-r--r--ppapi/cpp/point.h93
-rw-r--r--ppapi/cpp/ppp_entrypoints.cc52
-rw-r--r--ppapi/cpp/rect.cc137
-rw-r--r--ppapi/cpp/rect.h213
-rw-r--r--ppapi/cpp/resource.cc53
-rw-r--r--ppapi/cpp/resource.h58
-rw-r--r--ppapi/cpp/size.h108
-rw-r--r--ppapi/cpp/var.cc365
-rw-r--r--ppapi/cpp/var.h205
82 files changed, 7073 insertions, 0 deletions
diff --git a/ppapi/cpp/completion_callback.h b/ppapi/cpp/completion_callback.h
new file mode 100644
index 0000000..394271a
--- /dev/null
+++ b/ppapi/cpp/completion_callback.h
@@ -0,0 +1,313 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_COMPLETION_CALLBACK_H_
+#define PPAPI_CPP_COMPLETION_CALLBACK_H_
+
+#include "ppapi/c/pp_completion_callback.h"
+#include "ppapi/cpp/logging.h"
+#include "ppapi/cpp/non_thread_safe_ref_count.h"
+
+namespace pp {
+
+// A CompletionCallback provides a wrapper around PP_CompletionCallback.
+class CompletionCallback {
+ public:
+ // Use this special constructor to create a 'blocking' CompletionCallback
+ // that may be passed to a method to indicate that the calling thread should
+ // be blocked until the asynchronous operation corresponding to the method
+ // completes.
+ struct Block {};
+ CompletionCallback(Block) {
+ cc_ = PP_BlockUntilComplete();
+ }
+
+ CompletionCallback(PP_CompletionCallback_Func func, void* user_data) {
+ cc_ = PP_MakeCompletionCallback(func, user_data);
+ }
+
+ // Call this method to explicitly run the CompletionCallback. Normally, the
+ // system runs a CompletionCallback after an asynchronous operation
+ // completes, but programs may wish to run the CompletionCallback manually
+ // in order to reuse the same code paths.
+ void Run(int32_t result) {
+ PP_DCHECK(cc_.func);
+ PP_RunCompletionCallback(&cc_, result);
+ }
+
+ const PP_CompletionCallback& pp_completion_callback() const { return cc_; }
+
+ protected:
+ PP_CompletionCallback cc_;
+};
+
+// CompletionCallbackFactory<T> may be used to create CompletionCallback
+// objects that are bound to member functions.
+//
+// If a factory is destroyed, then any pending callbacks will be cancelled
+// preventing any bound member functions from being called. The CancelAll
+// method allows pending callbacks to be cancelled without destroying the
+// factory.
+//
+// NOTE: by default, CompletionCallbackFactory<T> isn't thread safe, but you can
+// make it more thread-friendly by passing a thread-safe refcounting class as
+// the second template element. However, it only guarantees safety for
+// *creating* a callback from another thread, the callback itself needs to
+// execute on the same thread as the thread that creates/destroys the factory.
+// With this restriction, it is safe to create the CompletionCallbackFactory on
+// the main thread, create callbacks from any thread and pass them to
+// CallOnMainThread.
+//
+// EXAMPLE USAGE:
+//
+// class MyHandler {
+// public:
+// MyHandler() : factory_(this), offset_(0) {
+// }
+//
+// void ProcessFile(const FileRef& file) {
+// CompletionCallback cc = factory_.NewCallback(&MyHandler::DidOpen);
+// int32_t rv = fio_.Open(file, PP_FileOpenFlag_Read, cc);
+// if (rv != PP_ERROR_WOULDBLOCK)
+// cc.Run(rv);
+// }
+//
+// private:
+// CompletionCallback NewCallback() {
+// return factory_.NewCallback(&MyHandler::DidCompleteIO);
+// }
+//
+// void DidOpen(int32_t result) {
+// if (result == PP_OK) {
+// // The file is open, and we can begin reading.
+// offset_ = 0;
+// ReadMore();
+// } else {
+// // Failed to open the file with error given by 'result'.
+// }
+// }
+//
+// void DidRead(int32_t result) {
+// if (result > 0) {
+// // buf_ now contains 'result' number of bytes from the file.
+// ProcessBytes(buf_, result);
+// offset_ += result;
+// ReadMore();
+// } else {
+// // Done reading (possibly with an error given by 'result').
+// }
+// }
+//
+// void ReadMore() {
+// CompletionCallback cc = factory_.NewCallback(&MyHandler::DidRead);
+// int32_t rv = fio_.Read(offset_, buf_, sizeof(buf_), cc);
+// if (rv != PP_ERROR_WOULDBLOCK)
+// cc.Run(rv);
+// }
+//
+// void ProcessBytes(const char* bytes, int32_t length) {
+// // Do work ...
+// }
+//
+// pp::CompletionCallbackFactory<MyHandler> factory_;
+// pp::FileIO fio_;
+// char buf_[4096];
+// int64_t offset_;
+// };
+//
+template <typename T, typename RefCount = NonThreadSafeRefCount>
+class CompletionCallbackFactory {
+ public:
+ explicit CompletionCallbackFactory(T* object = NULL)
+ : object_(object) {
+ InitBackPointer();
+ }
+
+ ~CompletionCallbackFactory() {
+ ResetBackPointer();
+ }
+
+ // Cancels all CompletionCallbacks allocated from this factory.
+ void CancelAll() {
+ ResetBackPointer();
+ InitBackPointer();
+ }
+
+ void Initialize(T* object) {
+ PP_DCHECK(object);
+ PP_DCHECK(!object_); // May only initialize once!
+ object_ = object;
+ }
+
+ T* GetObject() {
+ return object_;
+ }
+
+ // Allocates a new, single-use CompletionCallback. The CompletionCallback
+ // must be run in order for the memory allocated by NewCallback to be freed.
+ // If after passing the CompletionCallback to a PPAPI method, the method does
+ // not return PP_ERROR_WOULDBLOCK, then you should manually call the
+ // CompletionCallback's Run method otherwise memory will be leaked.
+
+ template <typename Method>
+ CompletionCallback NewCallback(Method method) {
+ PP_DCHECK(object_);
+ return NewCallbackHelper(Dispatcher0<Method>(method));
+ }
+
+ // A copy of "a" will be passed to "method" when the completion callback
+ // runs.
+ //
+ // Method should be of type:
+ // void (T::*)(int32_t result, const A& a)
+ //
+ template <typename Method, typename A>
+ CompletionCallback NewCallback(Method method, const A& a) {
+ PP_DCHECK(object_);
+ return NewCallbackHelper(Dispatcher1<Method, A>(method, a));
+ }
+
+ // A copy of "a" and "b" will be passed to "method" when the completion
+ // callback runs.
+ //
+ // Method should be of type:
+ // void (T::*)(int32_t result, const A& a, const B& b)
+ //
+ template <typename Method, typename A, typename B>
+ CompletionCallback NewCallback(Method method, const A& a, const B& b) {
+ PP_DCHECK(object_);
+ return NewCallbackHelper(Dispatcher2<Method, A, B>(method, a, b));
+ }
+
+ private:
+ class BackPointer {
+ public:
+ typedef CompletionCallbackFactory<T, RefCount> FactoryType;
+
+ BackPointer(FactoryType* factory)
+ : factory_(factory) {
+ }
+
+ void AddRef() {
+ ref_.AddRef();
+ }
+
+ void Release() {
+ if (ref_.Release() == 0)
+ delete this;
+ }
+
+ void DropFactory() {
+ factory_ = NULL;
+ }
+
+ T* GetObject() {
+ return factory_ ? factory_->GetObject() : NULL;
+ }
+
+ private:
+ RefCount ref_;
+ FactoryType* factory_;
+ };
+
+ template <typename Dispatcher>
+ class CallbackData {
+ public:
+ CallbackData(BackPointer* back_pointer, const Dispatcher& dispatcher)
+ : back_pointer_(back_pointer),
+ dispatcher_(dispatcher) {
+ back_pointer_->AddRef();
+ }
+
+ ~CallbackData() {
+ back_pointer_->Release();
+ }
+
+ static void Thunk(void* user_data, int32_t result) {
+ Self* self = static_cast<Self*>(user_data);
+ T* object = self->back_pointer_->GetObject();
+ if (object)
+ self->dispatcher_(object, result);
+ delete self;
+ }
+
+ private:
+ typedef CallbackData<Dispatcher> Self;
+ BackPointer* back_pointer_;
+ Dispatcher dispatcher_;
+ };
+
+ template <typename Method>
+ class Dispatcher0 {
+ public:
+ Dispatcher0(Method method) : method_(method) {
+ }
+ void operator()(T* object, int32_t result) {
+ (object->*method_)(result);
+ }
+ private:
+ Method method_;
+ };
+
+ template <typename Method, typename A>
+ class Dispatcher1 {
+ public:
+ Dispatcher1(Method method, const A& a)
+ : method_(method),
+ a_(a) {
+ }
+ void operator()(T* object, int32_t result) {
+ (object->*method_)(result, a_);
+ }
+ private:
+ Method method_;
+ A a_;
+ };
+
+ template <typename Method, typename A, typename B>
+ class Dispatcher2 {
+ public:
+ Dispatcher2(Method method, const A& a, const B& b)
+ : method_(method),
+ a_(a),
+ b_(b) {
+ }
+ void operator()(T* object, int32_t result) {
+ (object->*method_)(result, a_, b_);
+ }
+ private:
+ Method method_;
+ A a_;
+ B b_;
+ };
+
+ void InitBackPointer() {
+ back_pointer_ = new BackPointer(this);
+ back_pointer_->AddRef();
+ }
+
+ void ResetBackPointer() {
+ back_pointer_->DropFactory();
+ back_pointer_->Release();
+ }
+
+ template <typename Dispatcher>
+ CompletionCallback NewCallbackHelper(const Dispatcher& dispatcher) {
+ PP_DCHECK(object_); // Expects a non-null object!
+ return CompletionCallback(
+ &CallbackData<Dispatcher>::Thunk,
+ new CallbackData<Dispatcher>(back_pointer_, dispatcher));
+ }
+
+ // Disallowed:
+ CompletionCallbackFactory(const CompletionCallbackFactory&);
+ CompletionCallbackFactory& operator=(const CompletionCallbackFactory&);
+
+ T* object_;
+ BackPointer* back_pointer_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_COMPLETION_CALLBACK_H_
diff --git a/ppapi/cpp/core.cc b/ppapi/cpp/core.cc
new file mode 100644
index 0000000..5a24ecb
--- /dev/null
+++ b/ppapi/cpp/core.cc
@@ -0,0 +1,25 @@
+// Copyright (c) 2010 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/core.h"
+
+#include "ppapi/cpp/completion_callback.h"
+
+namespace pp {
+
+// This function is implemented in the .cc file to avoid including completion
+// callback all over the project.
+void Core::CallOnMainThread(int32_t delay_in_milliseconds,
+ const CompletionCallback& callback,
+ int32_t result) {
+ return interface_->CallOnMainThread(delay_in_milliseconds,
+ callback.pp_completion_callback(),
+ result);
+}
+
+bool Core::IsMainThread() {
+ return interface_->IsMainThread();
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/core.h b/ppapi/cpp/core.h
new file mode 100644
index 0000000..50c89d5
--- /dev/null
+++ b/ppapi/cpp/core.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_CORE_H_
+#define PPAPI_CPP_CORE_H_
+
+#include "ppapi/c/ppb_core.h"
+
+namespace pp {
+
+class CompletionCallback;
+class Module;
+
+// Simple wrapper around the PPB_Core interface. Some of these wrappers add
+// nothing over the C interface, but some allow the use of C++ arguments.
+class Core {
+ public:
+ // Note that we explicitly don't expose Resource& versions of this function
+ // since Resource will normally manage the refcount properly. These should
+ // be called only when doing manual management on raw PP_Resource handles,
+ // which should be fairly rare.
+ void AddRefResource(PP_Resource resource) {
+ interface_->AddRefResource(resource);
+ }
+ void ReleaseResource(PP_Resource resource) {
+ interface_->ReleaseResource(resource);
+ }
+
+ void* MemAlloc(size_t num_bytes) {
+ return interface_->MemAlloc(num_bytes);
+ }
+ void MemFree(void* ptr) {
+ interface_->MemFree(ptr);
+ }
+
+ PP_Time GetTime() {
+ return interface_->GetTime();
+ }
+
+ PP_TimeTicks GetTimeTicks() {
+ return interface_->GetTimeTicks();
+ }
+
+ void CallOnMainThread(int32_t delay_in_milliseconds,
+ const CompletionCallback& callback,
+ int32_t result = 0);
+
+ bool IsMainThread();
+
+ private:
+ // Allow Module to construct.
+ friend class Module;
+
+ // Only module should make this class so this constructor is private.
+ Core(const PPB_Core* inter) : interface_(inter) {}
+
+ // Copy and assignment are disallowed.
+ Core(const Core& other);
+ Core& operator=(const Core& other);
+
+ const PPB_Core* interface_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_CORE_H_
diff --git a/ppapi/cpp/dev/audio_config_dev.cc b/ppapi/cpp/dev/audio_config_dev.cc
new file mode 100644
index 0000000..c68dd84
--- /dev/null
+++ b/ppapi/cpp/dev/audio_config_dev.cc
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 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/dev/audio_config_dev.h"
+
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+DeviceFuncs<PPB_AudioConfig_Dev> audio_cfg_f(PPB_AUDIO_CONFIG_DEV_INTERFACE);
+
+namespace pp {
+
+AudioConfig_Dev::AudioConfig_Dev()
+ : sample_rate_(PP_AUDIOSAMPLERATE_NONE),
+ sample_frame_count_(0) {
+}
+
+AudioConfig_Dev::AudioConfig_Dev(PP_AudioSampleRate_Dev sample_rate,
+ uint32_t sample_frame_count)
+ : sample_rate_(sample_rate),
+ sample_frame_count_(sample_frame_count) {
+ if (audio_cfg_f) {
+ PassRefFromConstructor(audio_cfg_f->CreateStereo16Bit(
+ Module::Get()->pp_module(), sample_rate,
+ sample_frame_count));
+ }
+}
+
+// static
+uint32_t AudioConfig_Dev::RecommendSampleFrameCount(
+ uint32_t requested_sample_frame_count) {
+ if (!audio_cfg_f)
+ return 0;
+ return audio_cfg_f->RecommendSampleFrameCount(requested_sample_frame_count);
+}
+
+} // namespace pp
+
diff --git a/ppapi/cpp/dev/audio_config_dev.h b/ppapi/cpp/dev/audio_config_dev.h
new file mode 100644
index 0000000..1229156
--- /dev/null
+++ b/ppapi/cpp/dev/audio_config_dev.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_AUDIO_CONFIG_DEV_H_
+#define PPAPI_CPP_DEV_AUDIO_CONFIG_DEV_H_
+
+#include "ppapi/c/dev/ppb_audio_config_dev.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+// Typical usage:
+//
+// // Create an audio config with a supported frame count.
+// uint32_t sample_frame_count =
+// AudioConfig_Dev::RecommendSampleFrameCount(4096);
+// AudioConfig_Dev config(PP_AUDIOSAMPLERATE_44100, sample_frame_count);
+// if (config.is_null())
+// return false; // Couldn't configure audio.
+//
+// // Then use the config to create your audio resource.
+// Audio_dev audio(..., config, ...);
+// if (audio.is_null())
+// return false; // Couldn't create audio.
+class AudioConfig_Dev : public Resource {
+ public:
+ AudioConfig_Dev();
+
+ // Creates an audio config based on the given sample rate and frame count.
+ // If the rate and frame count aren't supported, the resulting resource
+ // will be is_null(). Pass the result of RecommendSampleFrameCount as the
+ // semple frame count.
+ //
+ // See PPB_AudioConfigDev.CreateStereo16Bit for more.
+ AudioConfig_Dev(PP_AudioSampleRate_Dev sample_rate,
+ uint32_t sample_frame_count);
+
+ // Returns a supported frame count for use in the constructor.
+ //
+ // See PPB_AudioConfigDev.RecommendSampleFrameCount.
+ static uint32_t RecommendSampleFrameCount(
+ uint32_t requested_sample_frame_count);
+
+ PP_AudioSampleRate_Dev sample_rate() const { return sample_rate_; }
+ uint32_t sample_frame_count() { return sample_frame_count_; }
+
+ private:
+ PP_AudioSampleRate_Dev sample_rate_;
+ uint32_t sample_frame_count_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_AUDIO_CONFIG_DEV_H_
+
diff --git a/ppapi/cpp/dev/audio_dev.cc b/ppapi/cpp/dev/audio_dev.cc
new file mode 100644
index 0000000..c747c78
--- /dev/null
+++ b/ppapi/cpp/dev/audio_dev.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 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/dev/audio_dev.h"
+
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_Audio_Dev> audio_f(PPB_AUDIO_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+Audio_Dev::Audio_Dev(const Instance& instance,
+ const AudioConfig_Dev& config,
+ PPB_Audio_Callback callback,
+ void* user_data)
+ : config_(config) {
+ if (audio_f) {
+ PassRefFromConstructor(audio_f->Create(instance.pp_instance(),
+ config.pp_resource(),
+ callback, user_data));
+ }
+}
+
+bool Audio_Dev::StartPlayback() {
+ return audio_f && audio_f->StartPlayback(pp_resource());
+}
+
+bool Audio_Dev::StopPlayback() {
+ return audio_f && audio_f->StopPlayback(pp_resource());
+}
+
+} // namespace pp
+
diff --git a/ppapi/cpp/dev/audio_dev.h b/ppapi/cpp/dev/audio_dev.h
new file mode 100644
index 0000000..983e53c
--- /dev/null
+++ b/ppapi/cpp/dev/audio_dev.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_AUDIO_DEV_H_
+#define PPAPI_CPP_DEV_AUDIO_DEV_H_
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/dev/ppb_audio_dev.h"
+#include "ppapi/cpp/dev/audio_config_dev.h"
+#include "ppapi/cpp/dev/buffer_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class Audio_Dev : public Resource {
+ public:
+ Audio_Dev() {}
+ Audio_Dev(const Instance& instance,
+ const AudioConfig_Dev& config,
+ PPB_Audio_Callback callback,
+ void* user_data);
+
+ AudioConfig_Dev& config() { return config_; }
+ const AudioConfig_Dev& config() const { return config_; }
+
+ bool StartPlayback();
+ bool StopPlayback();
+
+ private:
+ AudioConfig_Dev config_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_AUDIO_DEV_H_
+
diff --git a/ppapi/cpp/dev/buffer_dev.cc b/ppapi/cpp/dev/buffer_dev.cc
new file mode 100644
index 0000000..57ebed7
--- /dev/null
+++ b/ppapi/cpp/dev/buffer_dev.cc
@@ -0,0 +1,55 @@
+// Copyright (c) 2010 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/dev/buffer_dev.h"
+
+#include "ppapi/c/dev/ppb_buffer_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_Buffer_Dev> buffer_f(PPB_BUFFER_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+Buffer_Dev::Buffer_Dev() : data_(NULL), size_(0) {
+}
+
+Buffer_Dev::Buffer_Dev(const Buffer_Dev& other)
+ : Resource(other),
+ data_(other.data_),
+ size_(other.size_) {
+}
+
+Buffer_Dev::Buffer_Dev(int32_t size) : data_(NULL), size_(0) {
+ if (!buffer_f)
+ return;
+
+ PassRefFromConstructor(buffer_f->Create(Module::Get()->pp_module(), size));
+ if (!buffer_f->Describe(pp_resource(), &size_) ||
+ !(data_ = buffer_f->Map(pp_resource())))
+ *this = Buffer_Dev();
+}
+
+Buffer_Dev::~Buffer_Dev() {
+}
+
+Buffer_Dev& Buffer_Dev::operator=(const Buffer_Dev& other) {
+ Buffer_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void Buffer_Dev::swap(Buffer_Dev& other) {
+ Resource::swap(other);
+ std::swap(size_, other.size_);
+ std::swap(data_, other.data_);
+}
+
+} // namespace pp
+
diff --git a/ppapi/cpp/dev/buffer_dev.h b/ppapi/cpp/dev/buffer_dev.h
new file mode 100644
index 0000000..7497a6f
--- /dev/null
+++ b/ppapi/cpp/dev/buffer_dev.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_BUFFER_DEV_H_
+#define PPAPI_CPP_DEV_BUFFER_DEV_H_
+
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class Buffer_Dev : public Resource {
+ public:
+ // Creates an is_null() Buffer object.
+ Buffer_Dev();
+
+ Buffer_Dev(const Buffer_Dev& other);
+
+ // Allocates a new Buffer in the browser with the given size. The
+ // resulting object will be is_null() if the allocation failed.
+ explicit Buffer_Dev(int32_t size);
+
+ ~Buffer_Dev();
+
+ Buffer_Dev& operator=(const Buffer_Dev& other);
+ void swap(Buffer_Dev& other);
+
+ int32_t size() const { return size_; }
+ void* data() const { return data_; }
+
+ private:
+ void* data_;
+ int32_t size_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_BUFFER_DEV_H_
+
diff --git a/ppapi/cpp/dev/directory_entry_dev.cc b/ppapi/cpp/dev/directory_entry_dev.cc
new file mode 100644
index 0000000..a5f8179
--- /dev/null
+++ b/ppapi/cpp/dev/directory_entry_dev.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 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/dev/directory_entry_dev.h"
+
+#include <string.h>
+
+#include "ppapi/cpp/module.h"
+
+namespace pp {
+
+DirectoryEntry_Dev::DirectoryEntry_Dev() {
+ memset(&data_, 0, sizeof(data_));
+}
+
+DirectoryEntry_Dev::DirectoryEntry_Dev(const DirectoryEntry_Dev& other) {
+ data_.file_ref = other.data_.file_ref;
+ data_.file_type = other.data_.file_type;
+ if (data_.file_ref)
+ Module::Get()->core()->AddRefResource(data_.file_ref);
+}
+
+DirectoryEntry_Dev::~DirectoryEntry_Dev() {
+ if (data_.file_ref)
+ Module::Get()->core()->ReleaseResource(data_.file_ref);
+}
+
+DirectoryEntry_Dev& DirectoryEntry_Dev::operator=(
+ const DirectoryEntry_Dev& other) {
+ DirectoryEntry_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void DirectoryEntry_Dev::swap(DirectoryEntry_Dev& other) {
+ std::swap(data_.file_ref, other.data_.file_ref);
+ std::swap(data_.file_type, other.data_.file_type);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/directory_entry_dev.h b/ppapi/cpp/dev/directory_entry_dev.h
new file mode 100644
index 0000000..84ef623
--- /dev/null
+++ b/ppapi/cpp/dev/directory_entry_dev.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_DIRECTORY_ENTRY_DEV_H_
+#define PPAPI_CPP_DEV_DIRECTORY_ENTRY_DEV_H_
+
+#include "ppapi/c/dev/ppb_directory_reader_dev.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+
+namespace pp {
+
+class DirectoryEntry_Dev {
+ public:
+ DirectoryEntry_Dev();
+ DirectoryEntry_Dev(const DirectoryEntry_Dev& other);
+ ~DirectoryEntry_Dev();
+
+ DirectoryEntry_Dev& operator=(const DirectoryEntry_Dev& other);
+ void swap(DirectoryEntry_Dev& other);
+
+ // Returns true if the DirectoryEntry is invalid or uninitialized.
+ bool is_null() const { return !data_.file_ref; }
+
+ // Returns the FileRef held by this DirectoryEntry.
+ FileRef_Dev file_ref() const { return FileRef_Dev(data_.file_ref); }
+
+ // Returns the type of the file referenced by this DirectoryEntry.
+ PP_FileType_Dev file_type() const { return data_.file_type; }
+
+ private:
+ friend class DirectoryReader_Dev;
+ PP_DirectoryEntry_Dev data_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_DIRECTORY_ENTRY_DEV_H_
diff --git a/ppapi/cpp/dev/directory_reader_dev.cc b/ppapi/cpp/dev/directory_reader_dev.cc
new file mode 100644
index 0000000..bcf5e11
--- /dev/null
+++ b/ppapi/cpp/dev/directory_reader_dev.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2010 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/dev/directory_reader_dev.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/directory_entry_dev.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_DirectoryReader_Dev> directory_reader_f(
+ PPB_DIRECTORYREADER_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+DirectoryReader_Dev::DirectoryReader_Dev(const FileRef_Dev& directory_ref) {
+ if (!directory_reader_f)
+ return;
+ PassRefFromConstructor(
+ directory_reader_f->Create(directory_ref.pp_resource()));
+}
+
+DirectoryReader_Dev::DirectoryReader_Dev(const DirectoryReader_Dev& other)
+ : Resource(other) {
+}
+
+DirectoryReader_Dev& DirectoryReader_Dev::operator=(
+ const DirectoryReader_Dev& other) {
+ DirectoryReader_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void DirectoryReader_Dev::swap(DirectoryReader_Dev& other) {
+ Resource::swap(other);
+}
+
+int32_t DirectoryReader_Dev::GetNextEntry(DirectoryEntry_Dev* entry,
+ const CompletionCallback& cc) {
+ if (!directory_reader_f)
+ return PP_ERROR_NOINTERFACE;
+ return directory_reader_f->GetNextEntry(pp_resource(), &entry->data_,
+ cc.pp_completion_callback());
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/directory_reader_dev.h b/ppapi/cpp/dev/directory_reader_dev.h
new file mode 100644
index 0000000..e90fbc0
--- /dev/null
+++ b/ppapi/cpp/dev/directory_reader_dev.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_DIRECTORY_READER_DEV_H_
+#define PPAPI_CPP_DEV_DIRECTORY_READER_DEV_H_
+
+#include <stdlib.h>
+
+#include "ppapi/c/dev/ppb_directory_reader_dev.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class CompletionCallback;
+class DirectoryEntry_Dev;
+class FileRef_Dev;
+
+class DirectoryReader_Dev : public Resource {
+ public:
+ // Creates a DirectoryReader for the given directory.
+ DirectoryReader_Dev(const FileRef_Dev& directory_ref);
+
+ DirectoryReader_Dev(const DirectoryReader_Dev& other);
+
+ DirectoryReader_Dev& operator=(const DirectoryReader_Dev& other);
+ void swap(DirectoryReader_Dev& other);
+
+ // See PPB_DirectoryReader::GetNextEntry.
+ int32_t GetNextEntry(DirectoryEntry_Dev* entry,
+ const CompletionCallback& cc);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DIRECTORY_READER_H_
diff --git a/ppapi/cpp/dev/file_chooser_dev.cc b/ppapi/cpp/dev/file_chooser_dev.cc
new file mode 100644
index 0000000..051ab38
--- /dev/null
+++ b/ppapi/cpp/dev/file_chooser_dev.cc
@@ -0,0 +1,58 @@
+// Copyright (c) 2010 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/dev/file_chooser_dev.h"
+
+#include "ppapi/c/dev/ppb_file_chooser_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_FileChooser_Dev> file_chooser_f(PPB_FILECHOOSER_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+FileChooser_Dev::FileChooser_Dev(const Instance& instance,
+ const PP_FileChooserOptions_Dev& options) {
+ if (!file_chooser_f)
+ return;
+ PassRefFromConstructor(file_chooser_f->Create(instance.pp_instance(),
+ &options));
+}
+
+FileChooser_Dev::FileChooser_Dev(const FileChooser_Dev& other)
+ : Resource(other) {
+}
+
+FileChooser_Dev& FileChooser_Dev::operator=(const FileChooser_Dev& other) {
+ FileChooser_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void FileChooser_Dev::swap(FileChooser_Dev& other) {
+ Resource::swap(other);
+}
+
+int32_t FileChooser_Dev::Show(const CompletionCallback& cc) {
+ if (!file_chooser_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_chooser_f->Show(pp_resource(), cc.pp_completion_callback());
+}
+
+FileRef_Dev FileChooser_Dev::GetNextChosenFile() const {
+ if (!file_chooser_f)
+ return FileRef_Dev();
+ return FileRef_Dev(FileRef_Dev::PassRef(),
+ file_chooser_f->GetNextChosenFile(pp_resource()));
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/file_chooser_dev.h b/ppapi/cpp/dev/file_chooser_dev.h
new file mode 100644
index 0000000..f611b1e
--- /dev/null
+++ b/ppapi/cpp/dev/file_chooser_dev.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_FILE_CHOOSER_DEV_H_
+#define PPAPI_CPP_DEV_FILE_CHOOSER_DEV_H_
+
+#include "ppapi/cpp/resource.h"
+
+struct PP_FileChooserOptions_Dev;
+
+namespace pp {
+
+class CompletionCallback;
+class FileRef_Dev;
+class Instance;
+
+class FileChooser_Dev : public Resource {
+ public:
+ // Creates an is_null() FileChooser object.
+ FileChooser_Dev() {}
+
+ FileChooser_Dev(const Instance& instance,
+ const PP_FileChooserOptions_Dev& options);
+
+ FileChooser_Dev(const FileChooser_Dev& other);
+
+ FileChooser_Dev& operator=(const FileChooser_Dev& other);
+ void swap(FileChooser_Dev& other);
+
+ // PPB_FileChooser methods:
+ int32_t Show(const CompletionCallback& cc);
+ FileRef_Dev GetNextChosenFile() const;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_FILE_CHOOSER_DEV_H_
diff --git a/ppapi/cpp/dev/file_io_dev.cc b/ppapi/cpp/dev/file_io_dev.cc
new file mode 100644
index 0000000..54731ed
--- /dev/null
+++ b/ppapi/cpp/dev/file_io_dev.cc
@@ -0,0 +1,135 @@
+// Copyright (c) 2010 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/dev/file_io_dev.h"
+
+#include "ppapi/c/dev/ppb_file_io_dev.h"
+#include "ppapi/c/dev/ppb_file_io_trusted_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_FileIO_Dev> file_io_f(
+ PPB_FILEIO_DEV_INTERFACE);
+DeviceFuncs<PPB_FileIOTrusted_Dev> file_io_trusted_f(
+ PPB_FILEIOTRUSTED_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+FileIO_Dev::FileIO_Dev() {
+ if (!file_io_f)
+ return;
+ PassRefFromConstructor(file_io_f->Create(Module::Get()->pp_module()));
+}
+
+FileIO_Dev::FileIO_Dev(const FileIO_Dev& other)
+ : Resource(other) {
+}
+
+FileIO_Dev& FileIO_Dev::operator=(const FileIO_Dev& other) {
+ FileIO_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void FileIO_Dev::swap(FileIO_Dev& other) {
+ Resource::swap(other);
+}
+
+int32_t FileIO_Dev::Open(const FileRef_Dev& file_ref,
+ int32_t open_flags,
+ const CompletionCallback& cc) {
+ if (!file_io_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_f->Open(pp_resource(), file_ref.pp_resource(), open_flags,
+ cc.pp_completion_callback());
+}
+
+int32_t FileIO_Dev::Query(PP_FileInfo_Dev* result_buf,
+ const CompletionCallback& cc) {
+ if (!file_io_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_f->Query(pp_resource(), result_buf,
+ cc.pp_completion_callback());
+}
+
+int32_t FileIO_Dev::Touch(PP_Time last_access_time,
+ PP_Time last_modified_time,
+ const CompletionCallback& cc) {
+ if (!file_io_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_f->Touch(pp_resource(), last_access_time, last_modified_time,
+ cc.pp_completion_callback());
+}
+
+int32_t FileIO_Dev::Read(int64_t offset,
+ char* buffer,
+ int32_t bytes_to_read,
+ const CompletionCallback& cc) {
+ if (!file_io_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_f->Read(pp_resource(), offset, buffer, bytes_to_read,
+ cc.pp_completion_callback());
+}
+
+int32_t FileIO_Dev::Write(int64_t offset,
+ const char* buffer,
+ int32_t bytes_to_write,
+ const CompletionCallback& cc) {
+ if (!file_io_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_f->Write(pp_resource(), offset, buffer, bytes_to_write,
+ cc.pp_completion_callback());
+}
+
+int32_t FileIO_Dev::SetLength(int64_t length,
+ const CompletionCallback& cc) {
+ if (!file_io_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_f->SetLength(pp_resource(), length,
+ cc.pp_completion_callback());
+}
+
+int32_t FileIO_Dev::Flush(const CompletionCallback& cc) {
+ if (!file_io_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_f->Flush(pp_resource(), cc.pp_completion_callback());
+}
+
+void FileIO_Dev::Close() {
+ if (!file_io_f)
+ return;
+ file_io_f->Close(pp_resource());
+}
+
+int32_t FileIO_Dev::GetOSFileDescriptor() {
+ if (!file_io_trusted_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_trusted_f->GetOSFileDescriptor(pp_resource());
+}
+
+int32_t FileIO_Dev::WillWrite(int64_t offset,
+ int32_t bytes_to_write,
+ const CompletionCallback& cc) {
+ if (!file_io_trusted_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_trusted_f->WillWrite(pp_resource(), offset, bytes_to_write,
+ cc.pp_completion_callback());
+}
+
+int32_t FileIO_Dev::WillSetLength(int64_t length,
+ const CompletionCallback& cc) {
+ if (!file_io_trusted_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_io_trusted_f->WillSetLength(pp_resource(), length,
+ cc.pp_completion_callback());
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/file_io_dev.h b/ppapi/cpp/dev/file_io_dev.h
new file mode 100644
index 0000000..e38c2e1
--- /dev/null
+++ b/ppapi/cpp/dev/file_io_dev.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_FILE_IO_DEV_H_
+#define PPAPI_CPP_DEV_FILE_IO_DEV_H_
+
+#include "ppapi/c/pp_time.h"
+#include "ppapi/cpp/resource.h"
+
+struct PP_FileInfo_Dev;
+
+namespace pp {
+
+class CompletionCallback;
+class FileRef_Dev;
+
+class FileIO_Dev : public Resource {
+ public:
+ FileIO_Dev();
+ FileIO_Dev(const FileIO_Dev& other);
+
+ FileIO_Dev& operator=(const FileIO_Dev& other);
+ void swap(FileIO_Dev& other);
+
+ // PPB_FileIO methods:
+ int32_t Open(const FileRef_Dev& file_ref,
+ int32_t open_flags,
+ const CompletionCallback& cc);
+ int32_t Query(PP_FileInfo_Dev* result_buf,
+ const CompletionCallback& cc);
+ int32_t Touch(PP_Time last_access_time,
+ PP_Time last_modified_time,
+ const CompletionCallback& cc);
+ int32_t Read(int64_t offset,
+ char* buffer,
+ int32_t bytes_to_read,
+ const CompletionCallback& cc);
+ int32_t Write(int64_t offset,
+ const char* buffer,
+ int32_t bytes_to_write,
+ const CompletionCallback& cc);
+ int32_t SetLength(int64_t length,
+ const CompletionCallback& cc);
+ int32_t Flush(const CompletionCallback& cc);
+ void Close();
+
+ // PPB_FileIOTrusted methods:
+ // NOTE: These are only available to trusted plugins and will return
+ // PP_ERROR_NOINTERFACE if called from an untrusted plugin.
+ int32_t GetOSFileDescriptor();
+ int32_t WillWrite(int64_t offset,
+ int32_t bytes_to_write,
+ const CompletionCallback& cc);
+ int32_t WillSetLength(int64_t length,
+ const CompletionCallback& cc);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_FILE_IO_DEV_H_
diff --git a/ppapi/cpp/dev/file_ref_dev.cc b/ppapi/cpp/dev/file_ref_dev.cc
new file mode 100644
index 0000000..c65c07f
--- /dev/null
+++ b/ppapi/cpp/dev/file_ref_dev.cc
@@ -0,0 +1,124 @@
+// Copyright (c) 2010 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/dev/file_ref_dev.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/file_system_dev.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_FileRef_Dev> file_ref_f(PPB_FILEREF_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+FileRef_Dev::FileRef_Dev(PP_Resource resource) : Resource(resource) {
+}
+
+FileRef_Dev::FileRef_Dev(PassRef, PP_Resource resource) {
+ PassRefFromConstructor(resource);
+}
+
+FileRef_Dev::FileRef_Dev(const FileSystem_Dev& file_system,
+ const char* path) {
+ if (!file_ref_f)
+ return;
+ PassRefFromConstructor(file_ref_f->Create(file_system.pp_resource(), path));
+}
+
+FileRef_Dev::FileRef_Dev(const FileRef_Dev& other)
+ : Resource(other) {
+}
+
+FileRef_Dev& FileRef_Dev::operator=(const FileRef_Dev& other) {
+ FileRef_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void FileRef_Dev::swap(FileRef_Dev& other) {
+ Resource::swap(other);
+}
+
+PP_FileSystemType_Dev FileRef_Dev::GetFileSystemType() const {
+ if (!file_ref_f)
+ return PP_FILESYSTEMTYPE_EXTERNAL;
+ return file_ref_f->GetFileSystemType(pp_resource());
+}
+
+Var FileRef_Dev::GetName() const {
+ if (!file_ref_f)
+ return Var();
+ return Var(Var::PassRef(), file_ref_f->GetName(pp_resource()));
+}
+
+Var FileRef_Dev::GetPath() const {
+ if (!file_ref_f)
+ return Var();
+ return Var(Var::PassRef(), file_ref_f->GetPath(pp_resource()));
+}
+
+FileRef_Dev FileRef_Dev::GetParent() const {
+ if (!file_ref_f)
+ return FileRef_Dev();
+ return FileRef_Dev(PassRef(), file_ref_f->GetParent(pp_resource()));
+}
+
+int32_t FileRef_Dev::MakeDirectory(const CompletionCallback& cc) {
+ if (!file_ref_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_ref_f->MakeDirectory(pp_resource(),
+ false, // make_ancestors
+ cc.pp_completion_callback());
+}
+
+int32_t FileRef_Dev::MakeDirectoryIncludingAncestors(
+ const CompletionCallback& cc) {
+ if (!file_ref_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_ref_f->MakeDirectory(pp_resource(),
+ true, // make_ancestors
+ cc.pp_completion_callback());
+}
+
+int32_t FileRef_Dev::Query(PP_FileInfo_Dev* result_buf,
+ const CompletionCallback& cc) {
+ if (!file_ref_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_ref_f->Query(pp_resource(),
+ result_buf,
+ cc.pp_completion_callback());
+}
+
+int32_t FileRef_Dev::Touch(PP_Time last_access_time,
+ PP_Time last_modified_time,
+ const CompletionCallback& cc) {
+ if (!file_ref_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_ref_f->Touch(pp_resource(),
+ last_access_time,
+ last_modified_time,
+ cc.pp_completion_callback());
+}
+
+int32_t FileRef_Dev::Delete(const CompletionCallback& cc) {
+ if (!file_ref_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_ref_f->Delete(pp_resource(), cc.pp_completion_callback());
+}
+
+int32_t FileRef_Dev::Rename(const FileRef_Dev& new_file_ref,
+ const CompletionCallback& cc) {
+ if (!file_ref_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_ref_f->Rename(pp_resource(),
+ new_file_ref.pp_resource(),
+ cc.pp_completion_callback());
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/file_ref_dev.h b/ppapi/cpp/dev/file_ref_dev.h
new file mode 100644
index 0000000..b2d10a6
--- /dev/null
+++ b/ppapi/cpp/dev/file_ref_dev.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_FILE_REF_DEV_H_
+#define PPAPI_CPP_DEV_FILE_REF_DEV_H_
+
+#include "ppapi/c/dev/ppb_file_ref_dev.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+class CompletionCallback;
+class FileSystem_Dev;
+
+class FileRef_Dev : public Resource {
+ public:
+ // Creates an is_null() FileRef object.
+ FileRef_Dev() {}
+
+ // This constructor is used when we've gotten a PP_Resource as a return value
+ // that we need to addref.
+ explicit FileRef_Dev(PP_Resource resource);
+
+ // This constructor is used when we've gotten a PP_Resource as a return value
+ // that has already been addref'ed for us.
+ struct PassRef {};
+ FileRef_Dev(PassRef, PP_Resource resource);
+
+ // Creates a FileRef pointing to a path in the given filesystem.
+ FileRef_Dev(const FileSystem_Dev& file_system, const char* path);
+
+ FileRef_Dev(const FileRef_Dev& other);
+
+ FileRef_Dev& operator=(const FileRef_Dev& other);
+ void swap(FileRef_Dev& other);
+
+ // Returns the file system type.
+ PP_FileSystemType_Dev GetFileSystemType() const;
+
+ // Returns the name of the file.
+ Var GetName() const;
+
+ // Returns the absolute path of the file. See PPB_FileRef::GetPath for more
+ // details.
+ Var GetPath() const;
+
+ // Returns the parent directory of this file. See PPB_FileRef::GetParent for
+ // more details.
+ FileRef_Dev GetParent() const;
+
+ int32_t MakeDirectory(const CompletionCallback& cc);
+
+ int32_t MakeDirectoryIncludingAncestors(const CompletionCallback& cc);
+
+ int32_t Query(PP_FileInfo_Dev* result_buf, const CompletionCallback& cc);
+
+ int32_t Touch(PP_Time last_access_time,
+ PP_Time last_modified_time,
+ const CompletionCallback& cc);
+
+ int32_t Delete(const CompletionCallback& cc);
+
+ int32_t Rename(const FileRef_Dev& new_file_ref, const CompletionCallback& cc);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_FILE_REF_H_
diff --git a/ppapi/cpp/dev/file_system_dev.cc b/ppapi/cpp/dev/file_system_dev.cc
new file mode 100644
index 0000000..e6dfaff
--- /dev/null
+++ b/ppapi/cpp/dev/file_system_dev.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2010 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/dev/file_system_dev.h"
+
+#include "ppapi/c/dev/ppb_file_system_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_FileSystem_Dev> file_sys_f(PPB_FILESYSTEM_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+FileSystem_Dev::FileSystem_Dev(Instance* instance,
+ PP_FileSystemType_Dev type) {
+ if (!file_sys_f)
+ return;
+ PassRefFromConstructor(file_sys_f->Create(instance->pp_instance(), type));
+}
+
+int32_t FileSystem_Dev::Open(int64_t expected_size,
+ const CompletionCallback& cc) {
+ if (!file_sys_f)
+ return PP_ERROR_NOINTERFACE;
+ return file_sys_f->Open(pp_resource(), expected_size,
+ cc.pp_completion_callback());
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/file_system_dev.h b/ppapi/cpp/dev/file_system_dev.h
new file mode 100644
index 0000000..497740a
--- /dev/null
+++ b/ppapi/cpp/dev/file_system_dev.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_FILE_SYSTEM_DEV_H_
+#define PPAPI_CPP_DEV_FILE_SYSTEM_DEV_H_
+
+#include "ppapi/c/dev/pp_file_info_dev.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_time.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/resource.h"
+
+struct PP_FileInfo_Dev;
+
+namespace pp {
+
+class CompletionCallback;
+class FileRef_Dev;
+
+// Wraps methods from ppb_file_system.h
+class FileSystem_Dev : public Resource {
+ public:
+ FileSystem_Dev(Instance* instance, PP_FileSystemType_Dev type);
+
+ int32_t Open(int64_t expected_size, const CompletionCallback& cc);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_FILE_SYSTEM_DEV_H_
diff --git a/ppapi/cpp/dev/find_dev.cc b/ppapi/cpp/dev/find_dev.cc
new file mode 100644
index 0000000..8cbde54
--- /dev/null
+++ b/ppapi/cpp/dev/find_dev.cc
@@ -0,0 +1,75 @@
+// Copyright (c) 2010 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/dev/find_dev.h"
+
+#include "ppapi/c/dev/ppb_find_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+static const char kPPPFindInterface[] = PPP_FIND_DEV_INTERFACE;
+
+bool StartFind(PP_Instance instance,
+ const char* text,
+ bool case_sensitive) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPFindInterface);
+ if (!object)
+ return false;
+ return static_cast<Find_Dev*>(object)->StartFind(text, case_sensitive);
+}
+
+void SelectFindResult(PP_Instance instance, bool forward) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPFindInterface);
+ if (object)
+ static_cast<Find_Dev*>(object)->SelectFindResult(forward);
+}
+
+void StopFind(PP_Instance instance) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPFindInterface);
+ if (object)
+ static_cast<Find_Dev*>(object)->StopFind();
+}
+
+const PPP_Find_Dev ppp_find = {
+ &StartFind,
+ &SelectFindResult,
+ &StopFind
+};
+
+DeviceFuncs<PPB_Find_Dev> ppb_find_f(PPB_FIND_DEV_INTERFACE);
+
+} // namespace
+
+Find_Dev::Find_Dev(Instance* instance) : associated_instance_(instance) {
+ pp::Module::Get()->AddPluginInterface(kPPPFindInterface, &ppp_find);
+ associated_instance_->AddPerInstanceObject(kPPPFindInterface, this);
+}
+
+Find_Dev::~Find_Dev() {
+ associated_instance_->RemovePerInstanceObject(kPPPFindInterface, this);
+}
+
+void Find_Dev::NumberOfFindResultsChanged(int32_t total, bool final_result) {
+ if (ppb_find_f) {
+ ppb_find_f->NumberOfFindResultsChanged(associated_instance_->pp_instance(),
+ total, final_result);
+ }
+}
+
+void Find_Dev::SelectedFindResultChanged(int32_t index) {
+ if (ppb_find_f) {
+ ppb_find_f->SelectedFindResultChanged(associated_instance_->pp_instance(),
+ index);
+ }
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/find_dev.h b/ppapi/cpp/dev/find_dev.h
new file mode 100644
index 0000000..b89160f
--- /dev/null
+++ b/ppapi/cpp/dev/find_dev.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_FIND_DEV_H_
+#define PPAPI_CPP_DEV_FIND_DEV_H_
+
+#include <string>
+
+#include "ppapi/c/dev/ppp_find_dev.h"
+
+namespace pp {
+
+class Instance;
+
+// This class allows you to associate the PPP_Find and PPB_Find C-based
+// interfaces with an object. It associates itself with the given instance, and
+// registers as the global handler for handling the PPP_Find interface that the
+// browser calls.
+//
+// You would typically use this either via inheritance on your instance:
+// class MyInstance : public pp::Instance, public pp::Find_Dev {
+// class MyInstance() : pp::Find_Dev(this) {
+// }
+// ...
+// };
+//
+// or by composition:
+// class MyFinder : public pp::Find {
+// ...
+// };
+//
+// class MyInstance : public pp::Instance {
+// MyInstance() : finder_(this) {
+// }
+//
+// MyFinder finder_;
+// };
+class Find_Dev {
+ public:
+ // The instance parameter must outlive this class.
+ Find_Dev(Instance* instance);
+ virtual ~Find_Dev();
+
+ // PPP_Find_Dev functions exposed as virtual functions for you to
+ // override.
+ virtual bool StartFind(const std::string& text, bool case_sensitive) = 0;
+ virtual void SelectFindResult(bool forward) = 0;
+ virtual void StopFind() = 0;
+
+ // PPB_Find_Def functions for you to call to report find results.
+ void NumberOfFindResultsChanged(int32_t total, bool final_result);
+ void SelectedFindResultChanged(int32_t index);
+
+ private:
+ Instance* associated_instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_FIND_DEV_H_
diff --git a/ppapi/cpp/dev/font_dev.cc b/ppapi/cpp/dev/font_dev.cc
new file mode 100644
index 0000000..9e294fb
--- /dev/null
+++ b/ppapi/cpp/dev/font_dev.cc
@@ -0,0 +1,210 @@
+// Copyright (c) 2010 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/dev/font_dev.h"
+
+#include <algorithm>
+
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/point.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_Font_Dev> font_f(PPB_FONT_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+// FontDescription_Dev ---------------------------------------------------------
+
+FontDescription_Dev::FontDescription_Dev() {
+ pp_font_description_.face = face_.pp_var();
+ set_family(PP_FONTFAMILY_DEFAULT);
+ set_size(0);
+ set_weight(PP_FONTWEIGHT_NORMAL);
+ set_italic(false);
+ set_small_caps(false);
+ set_letter_spacing(0);
+ set_word_spacing(0);
+}
+
+FontDescription_Dev::FontDescription_Dev(const FontDescription_Dev& other) {
+ set_face(other.face());
+ set_family(other.family());
+ set_size(other.size());
+ set_weight(other.weight());
+ set_italic(other.italic());
+ set_small_caps(other.small_caps());
+ set_letter_spacing(other.letter_spacing());
+ set_word_spacing(other.word_spacing());
+}
+
+FontDescription_Dev::~FontDescription_Dev() {
+}
+
+FontDescription_Dev& FontDescription_Dev::operator=(
+ const FontDescription_Dev& other) {
+ FontDescription_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void FontDescription_Dev::swap(FontDescription_Dev& other) {
+ // Need to fix up both the face and the pp_font_description_.face which the
+ // setter does for us.
+ Var temp = face();
+ set_face(other.face());
+ other.set_face(temp);
+
+ std::swap(pp_font_description_.family, other.pp_font_description_.family);
+ std::swap(pp_font_description_.size, other.pp_font_description_.size);
+ std::swap(pp_font_description_.weight, other.pp_font_description_.weight);
+ std::swap(pp_font_description_.italic, other.pp_font_description_.italic);
+ std::swap(pp_font_description_.small_caps,
+ other.pp_font_description_.small_caps);
+ std::swap(pp_font_description_.letter_spacing,
+ other.pp_font_description_.letter_spacing);
+ std::swap(pp_font_description_.word_spacing,
+ other.pp_font_description_.word_spacing);
+}
+
+// TextRun_Dev -----------------------------------------------------------------
+
+TextRun_Dev::TextRun_Dev() {
+ pp_text_run_.text = text_.pp_var();
+ pp_text_run_.rtl = false;
+ pp_text_run_.override_direction = false;
+}
+
+TextRun_Dev::TextRun_Dev(const std::string& text,
+ bool rtl,
+ bool override_direction)
+ : text_(text) {
+ pp_text_run_.text = text_.pp_var();
+ pp_text_run_.rtl = rtl;
+ pp_text_run_.override_direction = override_direction;
+}
+
+TextRun_Dev::TextRun_Dev(const TextRun_Dev& other) : text_(other.text_) {
+ pp_text_run_.text = text_.pp_var();
+ pp_text_run_.rtl = other.pp_text_run_.rtl;
+ pp_text_run_.override_direction = other.pp_text_run_.override_direction;
+}
+
+TextRun_Dev::~TextRun_Dev() {
+}
+
+TextRun_Dev& TextRun_Dev::operator=(const TextRun_Dev& other) {
+ TextRun_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void TextRun_Dev::swap(TextRun_Dev& other) {
+ std::swap(text_, other.text_);
+
+ // Fix up both object's pp_text_run.text to point to their text_ member.
+ pp_text_run_.text = text_.pp_var();
+ other.pp_text_run_.text = other.text_.pp_var();
+
+ std::swap(pp_text_run_.rtl, other.pp_text_run_.rtl);
+ std::swap(pp_text_run_.override_direction,
+ other.pp_text_run_.override_direction);
+}
+
+// Font ------------------------------------------------------------------------
+
+Font_Dev::Font_Dev(PP_Resource resource) : Resource(resource) {
+}
+
+Font_Dev::Font_Dev(const FontDescription_Dev& description) {
+ if (!font_f)
+ return;
+ PassRefFromConstructor(font_f->Create(
+ Module::Get()->pp_module(), &description.pp_font_description()));
+}
+
+Font_Dev::Font_Dev(const Font_Dev& other) : Resource(other) {
+}
+
+Font_Dev& Font_Dev::operator=(const Font_Dev& other) {
+ Font_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void Font_Dev::swap(Font_Dev& other) {
+ Resource::swap(other);
+}
+
+bool Font_Dev::Describe(FontDescription_Dev* description,
+ PP_FontMetrics_Dev* metrics) const {
+ if (!font_f)
+ return false;
+
+ // Be careful with ownership of the |face| string. It will come back with
+ // a ref of 1, which we want to assign to the |face_| member of the C++ class.
+ if (!font_f->Describe(pp_resource(), &description->pp_font_description_,
+ metrics))
+ return false;
+ description->face_ = Var(Var::PassRef(),
+ description->pp_font_description_.face);
+
+ return true;
+}
+
+bool Font_Dev::DrawTextAt(ImageData* dest,
+ const TextRun_Dev& text,
+ const Point& position,
+ uint32_t color,
+ const Rect& clip,
+ bool image_data_is_opaque) const {
+ if (!font_f)
+ return false;
+ return font_f->DrawTextAt(pp_resource(), dest->pp_resource(),
+ &text.pp_text_run(), &position.pp_point(),
+ color, &clip.pp_rect(), image_data_is_opaque);
+}
+
+int32_t Font_Dev::MeasureText(const TextRun_Dev& text) const {
+ if (!font_f)
+ return -1;
+ return font_f->MeasureText(pp_resource(), &text.pp_text_run());
+}
+
+uint32_t Font_Dev::CharacterOffsetForPixel(const TextRun_Dev& text,
+ int32_t pixel_position) const {
+ if (!font_f)
+ return 0;
+ return font_f->CharacterOffsetForPixel(pp_resource(), &text.pp_text_run(),
+ pixel_position);
+
+}
+
+int32_t Font_Dev::PixelOffsetForCharacter(const TextRun_Dev& text,
+ uint32_t char_offset) const {
+ if (!font_f)
+ return 0;
+ return font_f->PixelOffsetForCharacter(pp_resource(), &text.pp_text_run(),
+ char_offset);
+}
+
+bool Font_Dev::DrawSimpleText(ImageData* dest,
+ const std::string& text,
+ const Point& position,
+ uint32_t color,
+ bool image_data_is_opaque) const {
+ return DrawTextAt(dest, TextRun_Dev(text), position, color,
+ Rect(dest->size()), image_data_is_opaque);
+}
+
+int32_t Font_Dev::MeasureSimpleText(const std::string& text) const {
+ return MeasureText(TextRun_Dev(text));
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/font_dev.h b/ppapi/cpp/dev/font_dev.h
new file mode 100644
index 0000000..bac8bb9
--- /dev/null
+++ b/ppapi/cpp/dev/font_dev.h
@@ -0,0 +1,139 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_FONT_DEV_H_
+#define PPAPI_CPP_DEV_FONT_DEV_H_
+
+#include <string>
+
+#include "ppapi/c/dev/ppb_font_dev.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/var.h"
+
+struct PP_FontDescription_Dev;
+
+namespace pp {
+
+class Font_dev;
+class ImageData;
+class Instance;
+class Point;
+class Rect;
+
+// FontDescription_Dev ---------------------------------------------------------
+
+class FontDescription_Dev {
+ public:
+ FontDescription_Dev();
+ FontDescription_Dev(const FontDescription_Dev& other);
+ ~FontDescription_Dev();
+
+ const PP_FontDescription_Dev& pp_font_description() const {
+ return pp_font_description_;
+ }
+
+ FontDescription_Dev& operator=(const FontDescription_Dev& other);
+ void swap(FontDescription_Dev& other);
+
+ Var face() const { return face_; }
+ void set_face(const Var& face) {
+ face_ = face;
+ pp_font_description_.face = face_.pp_var();
+ }
+
+ PP_FontFamily_Dev family() const { return pp_font_description_.family; }
+ void set_family(PP_FontFamily_Dev f) { pp_font_description_.family = f; }
+
+ uint32_t size() const { return pp_font_description_.size; }
+ void set_size(uint32_t s) { pp_font_description_.size = s; }
+
+ PP_FontWeight_Dev weight() const { return pp_font_description_.weight; }
+ void set_weight(PP_FontWeight_Dev w) { pp_font_description_.weight = w; }
+
+ bool italic() const { return pp_font_description_.italic; }
+ void set_italic(bool i) { pp_font_description_.italic = i; }
+
+ bool small_caps() const { return pp_font_description_.small_caps; }
+ void set_small_caps(bool s) { pp_font_description_.small_caps = s; }
+
+ int letter_spacing() const { return pp_font_description_.letter_spacing; }
+ void set_letter_spacing(int s) { pp_font_description_.letter_spacing = s; }
+
+ int word_spacing() const { return pp_font_description_.word_spacing; }
+ void set_word_spacing(int w) { pp_font_description_.word_spacing = w; }
+
+ private:
+ friend class Font_Dev;
+
+ Var face_; // Manages memory for pp_font_description_.face
+ PP_FontDescription_Dev pp_font_description_;
+};
+
+// TextRun_Dev ---------------------------------------------------------------------
+
+class TextRun_Dev {
+ public:
+ TextRun_Dev();
+ TextRun_Dev(const std::string& text,
+ bool rtl = false,
+ bool override_direction = false);
+ TextRun_Dev(const TextRun_Dev& other);
+ ~TextRun_Dev();
+
+ TextRun_Dev& operator=(const TextRun_Dev& other);
+ void swap(TextRun_Dev& other);
+
+ const PP_TextRun_Dev& pp_text_run() const {
+ return pp_text_run_;
+ }
+
+ private:
+ Var text_; // Manages memory for the reference in pp_text_run_.
+ PP_TextRun_Dev pp_text_run_;
+};
+
+// Font ------------------------------------------------------------------------
+
+// Provides access to system fonts.
+class Font_Dev : public Resource {
+ public:
+ // Creates an is_null() Font object.
+ Font_Dev() {}
+
+ explicit Font_Dev(PP_Resource resource);
+ explicit Font_Dev(const FontDescription_Dev& description);
+ Font_Dev(const Font_Dev& other);
+
+ Font_Dev& operator=(const Font_Dev& other);
+ void swap(Font_Dev& other);
+
+ // PPB_Font methods:
+ bool Describe(FontDescription_Dev* description,
+ PP_FontMetrics_Dev* metrics) const;
+ bool DrawTextAt(ImageData* dest,
+ const TextRun_Dev& text,
+ const Point& position,
+ uint32_t color,
+ const Rect& clip,
+ bool image_data_is_opaque) const;
+ int32_t MeasureText(const TextRun_Dev& text) const;
+ uint32_t CharacterOffsetForPixel(const TextRun_Dev& text,
+ int32_t pixel_position) const;
+ int32_t PixelOffsetForCharacter(const TextRun_Dev& text,
+ uint32_t char_offset) const;
+
+ // Convenience function that assumes a left-to-right string with no clipping.
+ bool DrawSimpleText(ImageData* dest,
+ const std::string& text,
+ const Point& position,
+ uint32_t color,
+ bool image_data_is_opaque = false) const;
+
+ // Convenience function that assumes a left-to-right string.
+ int32_t MeasureSimpleText(const std::string& text) const;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_FONT_DEV_H_
diff --git a/ppapi/cpp/dev/fullscreen_dev.cc b/ppapi/cpp/dev/fullscreen_dev.cc
new file mode 100644
index 0000000..fd04ec9
--- /dev/null
+++ b/ppapi/cpp/dev/fullscreen_dev.cc
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 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/dev/fullscreen_dev.h"
+
+#include "ppapi/c/dev/ppb_fullscreen_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+DeviceFuncs<PPB_Fullscreen_Dev> ppb_fullscreen_f(PPB_FULLSCREEN_DEV_INTERFACE);
+
+} // anonymous namespace
+
+Fullscreen_Dev::Fullscreen_Dev(Instance* instance)
+ : associated_instance_(instance) {
+}
+
+Fullscreen_Dev::~Fullscreen_Dev() {
+}
+
+bool Fullscreen_Dev::IsFullscreen() {
+ return ppb_fullscreen_f && ppb_fullscreen_f->IsFullscreen(
+ associated_instance_->pp_instance());
+}
+
+bool Fullscreen_Dev::SetFullscreen(bool fullscreen) {
+ if (!ppb_fullscreen_f)
+ return false;
+ return ppb_fullscreen_f->SetFullscreen(associated_instance_->pp_instance(),
+ fullscreen);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/fullscreen_dev.h b/ppapi/cpp/dev/fullscreen_dev.h
new file mode 100644
index 0000000..1050faf
--- /dev/null
+++ b/ppapi/cpp/dev/fullscreen_dev.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_FULLSCREEN_DEV_H_
+#define PPAPI_CPP_DEV_FULLSCREEN_DEV_H_
+
+#include <string>
+
+#include "ppapi/c/dev/ppb_fullscreen_dev.h"
+
+namespace pp {
+
+class Instance;
+
+class Fullscreen_Dev {
+ public:
+ Fullscreen_Dev(Instance* instance);
+ virtual ~Fullscreen_Dev();
+
+ // PPB_Fullscreen_Dev methods.
+ bool IsFullscreen();
+ bool SetFullscreen(bool fullscreen);
+
+ private:
+ Instance* associated_instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_FULLSCREEN_DEV_H_
diff --git a/ppapi/cpp/dev/graphics_3d_client_dev.cc b/ppapi/cpp/dev/graphics_3d_client_dev.cc
new file mode 100644
index 0000000..bdd2e7e
--- /dev/null
+++ b/ppapi/cpp/dev/graphics_3d_client_dev.cc
@@ -0,0 +1,43 @@
+// Copyright (c) 2010 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/dev/graphics_3d_client_dev.h"
+
+#include "ppapi/c/dev/ppp_graphics_3d_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+const char kPPPGraphics3DInterface[] = PPP_GRAPHICS_3D_DEV_INTERFACE;
+
+void Graphics3D_ContextLost(PP_Instance instance) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPGraphics3DInterface);
+ if (!object)
+ return;
+ return static_cast<Graphics3DClient_Dev*>(object)->Graphics3DContextLost();
+}
+
+static PPP_Graphics3D_Dev graphics3d_interface = {
+ &Graphics3D_ContextLost,
+};
+
+} // namespace
+
+Graphics3DClient_Dev::Graphics3DClient_Dev(Instance* instance)
+ : associated_instance_(instance) {
+ pp::Module::Get()->AddPluginInterface(kPPPGraphics3DInterface,
+ &graphics3d_interface);
+ associated_instance_->AddPerInstanceObject(kPPPGraphics3DInterface, this);
+}
+
+Graphics3DClient_Dev::~Graphics3DClient_Dev() {
+ associated_instance_->RemovePerInstanceObject(kPPPGraphics3DInterface, this);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/graphics_3d_client_dev.h b/ppapi/cpp/dev/graphics_3d_client_dev.h
new file mode 100644
index 0000000..5f68fb2
--- /dev/null
+++ b/ppapi/cpp/dev/graphics_3d_client_dev.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_GRAPHICS_3D_CLIENT_DEV_H_
+#define PPAPI_CPP_DEV_GRAPHICS_3D_CLIENT_DEV_H_
+
+#include "ppapi/c/pp_stdint.h"
+
+namespace pp {
+
+class Instance;
+class Rect;
+class Scrollbar_Dev;
+class Widget_Dev;
+
+// This class provides a C++ interface for callbacks related to 3D. You
+// would normally use multiple inheritance to derive from this class in your
+// instance.
+class Graphics3DClient_Dev {
+ public:
+ Graphics3DClient_Dev(Instance* instance);
+ virtual ~Graphics3DClient_Dev();
+
+ /**
+ * Notification that the context was lost for the 3D devices.
+ */
+ virtual void Graphics3DContextLost() = 0;
+
+ private:
+ Instance* associated_instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_GRAPHICS_3D_CLIENT_DEV_H_
diff --git a/ppapi/cpp/dev/graphics_3d_dev.cc b/ppapi/cpp/dev/graphics_3d_dev.cc
new file mode 100644
index 0000000..766b70c
--- /dev/null
+++ b/ppapi/cpp/dev/graphics_3d_dev.cc
@@ -0,0 +1,117 @@
+// Copyright (c) 2010 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/dev/graphics_3d_dev.h"
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+extern "C" {
+const PPB_OpenGLES_Dev* pepper_opengl_interface = NULL;
+}
+
+namespace {
+
+DeviceFuncs<PPB_Graphics3D_Dev> graphics_3d_f(PPB_GRAPHICS_3D_DEV_INTERFACE);
+DeviceFuncs<PPB_OpenGLES_Dev> opengles_f(PPB_OPENGLES_DEV_INTERFACE);
+
+inline void InitializeOpenGLCInterface() {
+ if (!pepper_opengl_interface)
+ pepper_opengl_interface = &(*opengles_f);
+}
+
+} // namespace
+
+namespace pp {
+
+// static
+bool Graphics3D_Dev::GetConfigs(int32_t *configs, int32_t config_size,
+ int32_t *num_config) {
+ if (graphics_3d_f)
+ return graphics_3d_f->GetConfigs(configs, config_size, num_config);
+ return false;
+}
+
+// static
+bool Graphics3D_Dev::ChooseConfig(const int32_t *attrib_list, int32_t *configs,
+ int32_t config_size, int32_t *num_config) {
+ if (graphics_3d_f)
+ return graphics_3d_f->ChooseConfig(attrib_list, configs, config_size,
+ num_config);
+ return false;
+}
+
+// static
+bool Graphics3D_Dev::GetConfigAttrib(int32_t config, int32_t attribute,
+ int32_t *value) {
+ if (graphics_3d_f)
+ return graphics_3d_f->GetConfigAttrib(config, attribute, value);
+ return false;
+}
+
+// static
+const char* Graphics3D_Dev::QueryString(int32_t name) {
+ if (graphics_3d_f)
+ return graphics_3d_f->QueryString(name);
+ return NULL;
+}
+
+// static
+void* Graphics3D_Dev::GetProcAddress(const char* name) {
+ if (graphics_3d_f)
+ return graphics_3d_f->GetProcAddress(name);
+ return NULL;
+}
+
+Graphics3D_Dev Graphics3D_Dev::FromResource(PP_Resource resource_id) {
+ if (graphics_3d_f && graphics_3d_f->IsGraphics3D(resource_id))
+ return Graphics3D_Dev(resource_id);
+ return Graphics3D_Dev();
+}
+
+bool Graphics3D_Dev::ResetCurrent() {
+ return graphics_3d_f && graphics_3d_f->MakeCurent(0);
+}
+
+Graphics3D_Dev Graphics3D_Dev::GetCurrentContext() {
+ if (graphics_3d_f)
+ return FromResource(graphics_3d_f->GetCurrentContext());
+ return Graphics3D_Dev();
+}
+
+uint32_t Graphics3D_Dev::GetError() {
+ if (graphics_3d_f)
+ return graphics_3d_f->GetError();
+ return PP_GRAPHICS_3D_ERROR_NOT_INITIALIZED;
+}
+
+const PPB_OpenGLES_Dev* Graphics3D_Dev::GetImplementation() {
+ return &(*opengles_f);
+}
+
+Graphics3D_Dev::Graphics3D_Dev(const Instance& instance,
+ int32_t config,
+ int32_t share_context,
+ const int32_t* attrib_list) {
+ if (graphics_3d_f && opengles_f) {
+ InitializeOpenGLCInterface();
+ PassRefFromConstructor(graphics_3d_f->CreateContext(instance.pp_instance(),
+ config, share_context,
+ attrib_list));
+ }
+}
+
+bool Graphics3D_Dev::MakeCurrent() const {
+ InitializeOpenGLCInterface();
+ return graphics_3d_f && graphics_3d_f->MakeCurent(pp_resource());
+}
+
+bool Graphics3D_Dev::SwapBuffers() const {
+ return graphics_3d_f && graphics_3d_f->SwapBuffers(pp_resource());
+}
+
+} // namespace pp
+
diff --git a/ppapi/cpp/dev/graphics_3d_dev.h b/ppapi/cpp/dev/graphics_3d_dev.h
new file mode 100644
index 0000000..88fe47d
--- /dev/null
+++ b/ppapi/cpp/dev/graphics_3d_dev.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_GRAPHICS_3D_DEV_H_
+#define PPAPI_CPP_DEV_GRAPHICS_3D_DEV_H_
+
+#include "ppapi/c/dev/ppb_graphics_3d_dev.h"
+#include "ppapi/c/dev/ppb_opengles_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class Graphics3D_Dev : public Resource {
+ public:
+ static bool GetConfigs(int32_t* configs, int32_t config_size,
+ int32_t* num_config);
+
+ static bool ChooseConfig(const int32_t* attrib_list, int32_t* configs,
+ int32_t config_size, int32_t* num_config);
+
+ static bool GetConfigAttrib(int32_t config, int32_t attribute,
+ int32_t* value);
+
+ static const char* QueryString(int32_t name);
+
+ static void* GetProcAddress(const char* name);
+
+ static bool ResetCurrent();
+ static Graphics3D_Dev GetCurrentContext();
+ static uint32_t GetError();
+ static const PPB_OpenGLES_Dev* GetImplementation();
+
+ // Creates an is_null() Graphics3D object.
+ Graphics3D_Dev() {}
+
+ Graphics3D_Dev(const Instance& instance,
+ int32_t config,
+ int32_t share_context,
+ const int32_t* attrib_list);
+
+ bool MakeCurrent() const;
+ bool SwapBuffers() const;
+
+ protected:
+ explicit Graphics3D_Dev(PP_Resource resource_id) : Resource(resource_id) {}
+ static Graphics3D_Dev FromResource(PP_Resource resource_id);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_GRAPHICS_3D_DEV_H_
+
diff --git a/ppapi/cpp/dev/printing_dev.cc b/ppapi/cpp/dev/printing_dev.cc
new file mode 100644
index 0000000..a5aa361
--- /dev/null
+++ b/ppapi/cpp/dev/printing_dev.cc
@@ -0,0 +1,74 @@
+// Copyright (c) 2010 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/dev/printing_dev.h"
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+static const char kPPPPrintingInterface[] = PPP_PRINTING_DEV_INTERFACE;
+
+PP_PrintOutputFormat_Dev* QuerySupportedFormats(PP_Instance instance,
+ uint32_t* format_count) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPPrintingInterface);
+ if (!object)
+ return NULL;
+ return static_cast<Printing_Dev*>(object)->QuerySupportedPrintOutputFormats(
+ format_count);
+}
+
+int32_t Begin(PP_Instance instance,
+ const struct PP_PrintSettings_Dev* print_settings) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPPrintingInterface);
+ if (!object)
+ return 0;
+ return static_cast<Printing_Dev*>(object)->PrintBegin(*print_settings);
+}
+
+PP_Resource PrintPages(PP_Instance instance,
+ const struct PP_PrintPageNumberRange_Dev* page_ranges,
+ uint32_t page_range_count) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPPrintingInterface);
+ if (!object)
+ return 0;
+ return static_cast<Printing_Dev*>(object)->PrintPages(
+ page_ranges, page_range_count).detach();
+}
+
+void End(PP_Instance instance) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPPrintingInterface);
+ if (object)
+ static_cast<Printing_Dev*>(object)->PrintEnd();
+}
+
+const PPP_Printing_Dev ppp_printing = {
+ &QuerySupportedFormats,
+ &Begin,
+ &PrintPages,
+ &End
+};
+
+} // namespace
+
+Printing_Dev::Printing_Dev(Instance* instance)
+ : associated_instance_(instance) {
+ pp::Module::Get()->AddPluginInterface(kPPPPrintingInterface, &ppp_printing);
+ associated_instance_->AddPerInstanceObject(kPPPPrintingInterface, this);
+}
+
+Printing_Dev::~Printing_Dev() {
+ associated_instance_->RemovePerInstanceObject(kPPPPrintingInterface, this);
+}
+
+} // namespace pp
+
diff --git a/ppapi/cpp/dev/printing_dev.h b/ppapi/cpp/dev/printing_dev.h
new file mode 100644
index 0000000..ca34ba3
--- /dev/null
+++ b/ppapi/cpp/dev/printing_dev.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_PRINTING_DEV_H_
+#define PPAPI_CPP_DEV_PRINTING_DEV_H_
+
+#include "ppapi/c/dev/ppp_printing_dev.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class Instance;
+
+// You would typically use this either via inheritance on your instance or
+// by composition: see find_dev.h for an example.
+class Printing_Dev {
+ public:
+ // The instance parameter must outlive this class.
+ explicit Printing_Dev(Instance* instance);
+ virtual ~Printing_Dev();
+
+ // PPP_Printing_Dev functions exposed as virtual functions for you to
+ // override.
+ virtual PP_PrintOutputFormat_Dev* QuerySupportedPrintOutputFormats(
+ uint32_t* format_count) = 0;
+ virtual int32_t PrintBegin(const PP_PrintSettings_Dev& print_settings) = 0;
+ virtual Resource PrintPages(const PP_PrintPageNumberRange_Dev* page_ranges,
+ uint32_t page_range_count) = 0;
+ virtual void PrintEnd() = 0;
+
+ private:
+ Instance* associated_instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_PRINTING_DEV_H_
diff --git a/ppapi/cpp/dev/scriptable_object_deprecated.cc b/ppapi/cpp/dev/scriptable_object_deprecated.cc
new file mode 100644
index 0000000..59f44d1
--- /dev/null
+++ b/ppapi/cpp/dev/scriptable_object_deprecated.cc
@@ -0,0 +1,188 @@
+// Copyright (c) 2010 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/dev/scriptable_object_deprecated.h"
+
+#include "ppapi/c/dev/ppp_class_deprecated.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+namespace deprecated {
+
+namespace {
+
+// Allows converting an output param of a Var to an output param of a PP_Var
+// for exceptions. The object is only copied if it is not void, which we
+// take to mean an exception occurred.
+class ExceptionConverter {
+ public:
+ ExceptionConverter(PP_Var* out) : out_(out) {
+ }
+ ~ExceptionConverter() {
+ if (!exception_.is_undefined())
+ *out_ = exception_.Detach();
+ }
+
+ Var* Get() { return &exception_; }
+
+ private:
+ PP_Var* out_;
+ Var exception_;
+};
+
+// Used internally to convert a C-style array of PP_Var to a vector of Var.
+void ArgListToVector(uint32_t argc, PP_Var* argv, std::vector<Var>* output) {
+ output->reserve(argc);
+ for (size_t i = 0; i < argc; i++)
+ output->push_back(Var(Var::DontManage(), argv[i]));
+}
+
+bool HasProperty(void* object, PP_Var name, PP_Var* exception) {
+ ExceptionConverter e(exception);
+ return static_cast<ScriptableObject*>(object)->HasProperty(
+ Var(Var::DontManage(), name), e.Get());
+}
+
+bool HasMethod(void* object, PP_Var name, PP_Var* exception) {
+ ExceptionConverter e(exception);
+ return static_cast<ScriptableObject*>(object)->HasMethod(
+ Var(Var::DontManage(), name), e.Get());
+}
+
+PP_Var GetProperty(void* object,
+ PP_Var name,
+ PP_Var* exception) {
+ ExceptionConverter e(exception);
+ return static_cast<ScriptableObject*>(object)->GetProperty(
+ Var(Var::DontManage(), name), e.Get()).Detach();
+}
+
+void GetAllPropertyNames(void* object,
+ uint32_t* property_count,
+ PP_Var** properties,
+ PP_Var* exception) {
+ ExceptionConverter e(exception);
+ std::vector<Var> props;
+ static_cast<ScriptableObject*>(object)->GetAllPropertyNames(&props, e.Get());
+ if (props.empty())
+ return;
+ *property_count = static_cast<uint32_t>(props.size());
+ *properties = static_cast<PP_Var*>(
+ Module::Get()->core()->MemAlloc(sizeof(PP_Var) * props.size()));
+ for (size_t i = 0; i < props.size(); ++i)
+ (*properties)[i] = props[i].Detach();
+}
+
+void SetProperty(void* object,
+ PP_Var name,
+ PP_Var value,
+ PP_Var* exception) {
+ ExceptionConverter e(exception);
+ static_cast<ScriptableObject*>(object)->SetProperty(
+ Var(Var::DontManage(), name), Var(Var::DontManage(), value), e.Get());
+}
+
+void RemoveProperty(void* object,
+ PP_Var name,
+ PP_Var* exception) {
+ ExceptionConverter e(exception);
+ static_cast<ScriptableObject*>(object)->RemoveProperty(
+ Var(Var::DontManage(), name), e.Get());
+}
+
+PP_Var Call(void* object,
+ PP_Var method_name,
+ uint32_t argc,
+ PP_Var* argv,
+ PP_Var* exception) {
+ ExceptionConverter e(exception);
+
+ std::vector<Var> args;
+ ArgListToVector(argc, argv, &args);
+ return static_cast<ScriptableObject*>(object)->Call(
+ Var(Var::DontManage(), method_name), args, e.Get()).Detach();
+}
+
+PP_Var Construct(void* object,
+ uint32_t argc,
+ PP_Var* argv,
+ PP_Var* exception) {
+ ExceptionConverter e(exception);
+
+ std::vector<Var> args;
+ ArgListToVector(argc, argv, &args);
+ return static_cast<ScriptableObject*>(object)->Construct(
+ args, e.Get()).Detach();
+}
+
+void Deallocate(void* object) {
+ delete static_cast<ScriptableObject*>(object);
+}
+
+PPP_Class_Deprecated plugin_class = {
+ &HasProperty,
+ &HasMethod,
+ &GetProperty,
+ &GetAllPropertyNames,
+ &SetProperty,
+ &RemoveProperty,
+ &Call,
+ &Construct,
+ &Deallocate
+};
+
+} // namespace
+
+bool ScriptableObject::HasProperty(const Var& /*name*/, Var* /*exception*/) {
+ return false;
+}
+
+bool ScriptableObject::HasMethod(const Var& /*name*/, Var* /*exception*/) {
+ return false;
+}
+
+Var ScriptableObject::GetProperty(const Var& /*name*/, Var* exception) {
+ *exception = Var("Property does not exist on ScriptableObject");
+ return Var();
+}
+
+void ScriptableObject::GetAllPropertyNames(std::vector<Var>* /*properties*/,
+ Var* /*exception*/) {
+}
+
+void ScriptableObject::SetProperty(const Var& /*name*/,
+ const Var& /*value*/,
+ Var* exception) {
+ *exception = Var("Property can not be set on ScriptableObject");
+}
+
+void ScriptableObject::RemoveProperty(const Var& /*name*/,
+ Var* exception) {
+ *exception = Var(
+ "Property does does not exist to be removed in ScriptableObject");
+}
+
+Var ScriptableObject::Call(const Var& /*method_name*/,
+ const std::vector<Var>& /*args*/,
+ Var* exception) {
+ *exception = Var("Method does not exist to call in ScriptableObject");
+ return Var();
+}
+
+Var ScriptableObject::Construct(const std::vector<Var>& /*args*/,
+ Var* exception) {
+ *exception = Var("Constuct method does not exist in ScriptableObject");
+ return Var();
+}
+
+// static
+const PPP_Class_Deprecated* ScriptableObject::GetClass() {
+ return &plugin_class;
+}
+
+} // namespace deprecated
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/scriptable_object_deprecated.h b/ppapi/cpp/dev/scriptable_object_deprecated.h
new file mode 100644
index 0000000..42ab466
--- /dev/null
+++ b/ppapi/cpp/dev/scriptable_object_deprecated.h
@@ -0,0 +1,92 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_SCRIPTABLE_OBJECT_DEPRECATED_H_
+#define PPAPI_CPP_SCRIPTABLE_OBJECT_DEPRECATED_H_
+
+#include <vector>
+
+struct PPP_Class_Deprecated;
+
+namespace pp {
+class Var;
+}
+using pp::Var;
+
+namespace pp {
+
+namespace deprecated {
+
+// This class allows you to implement objects accessible by JavaScript. Derive
+// from this class and override the virtual functions you support. pp::Var has
+// a constructor that takes a pointer to a ScriptableObject for when you want
+// to convert your custom object to a var.
+//
+// Please see the PPB_Core C interface for more information on how to implement
+// these functions. These functions are the backend implementation for the
+// functions in PPB_Var, which contains further information.
+//
+// Please see:
+// http://code.google.com/p/ppapi/wiki/InterfacingWithJavaScript
+// for a general overview of interfacing with JavaScript.
+class ScriptableObject {
+ public:
+ ScriptableObject() {}
+ virtual ~ScriptableObject() {}
+
+ // The default implementation returns false.
+ virtual bool HasProperty(const Var& name, Var* exception);
+
+ // The default implementation returns false.
+ virtual bool HasMethod(const Var& name, Var* exception);
+
+ // The default implementation sets an exception that the property doesn't
+ // exist.
+ virtual Var GetProperty(const Var& name, Var* exception);
+
+ // The default implementation returns no properties.
+ virtual void GetAllPropertyNames(std::vector<Var>* properties,
+ Var* exception);
+
+ // The default implementation sets an exception that the property can not be
+ // set.
+ virtual void SetProperty(const Var& name,
+ const Var& value,
+ Var* exception);
+
+ // The default implementation sets an exception that the method does not
+ // exist.
+ virtual void RemoveProperty(const Var& name,
+ Var* exception);
+
+ // TODO(brettw) need native array access here.
+
+ // method_name is guaranteed to be either a string or an integer.
+ //
+ // The default implementation sets an exception that the method does not
+ // exist.
+ virtual Var Call(const Var& method_name,
+ const std::vector<Var>& args,
+ Var* exception);
+
+ // The default implementation sets an exception that the method does not
+ // exist.
+ virtual Var Construct(const std::vector<Var>& args,
+ Var* exception);
+
+ private:
+ friend class ::pp::Var;
+ static const PPP_Class_Deprecated* GetClass();
+
+ // Unimplemented, copy and assigmnent is not allowed.
+ ScriptableObject(const ScriptableObject& other);
+ ScriptableObject& operator=(const ScriptableObject& other);
+};
+
+} // namespace deprecated
+
+} // namespace pp
+
+#endif // PPAPI_CPP_SCRIPTABLE_OBJECT_DEPRECATED_H_
+
diff --git a/ppapi/cpp/dev/scrollbar_dev.cc b/ppapi/cpp/dev/scrollbar_dev.cc
new file mode 100644
index 0000000..23395ef
--- /dev/null
+++ b/ppapi/cpp/dev/scrollbar_dev.cc
@@ -0,0 +1,84 @@
+// Copyright (c) 2010 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 <vector>
+
+#include "ppapi/cpp/dev/scrollbar_dev.h"
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+#include "ppapi/cpp/rect.h"
+
+namespace {
+
+DeviceFuncs<PPB_Scrollbar_Dev> scrollbar_f(PPB_SCROLLBAR_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+Scrollbar_Dev::Scrollbar_Dev(PP_Resource resource) : Widget_Dev(resource) {
+}
+
+Scrollbar_Dev::Scrollbar_Dev(const Instance& instance, bool vertical) {
+ if (!scrollbar_f)
+ return;
+ PassRefFromConstructor(scrollbar_f->Create(instance.pp_instance(), vertical));
+}
+
+Scrollbar_Dev::Scrollbar_Dev(const Scrollbar_Dev& other)
+ : Widget_Dev(other) {
+}
+
+Scrollbar_Dev& Scrollbar_Dev::operator=(const Scrollbar_Dev& other) {
+ Scrollbar_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void Scrollbar_Dev::swap(Scrollbar_Dev& other) {
+ Resource::swap(other);
+}
+
+uint32_t Scrollbar_Dev::GetThickness() {
+ if (!scrollbar_f)
+ return 0;
+ return scrollbar_f->GetThickness();
+}
+
+uint32_t Scrollbar_Dev::GetValue() {
+ if (!scrollbar_f)
+ return 0;
+ return scrollbar_f->GetValue(pp_resource());
+}
+
+void Scrollbar_Dev::SetValue(uint32_t value) {
+ if (scrollbar_f)
+ scrollbar_f->SetValue(pp_resource(), value);
+}
+
+void Scrollbar_Dev::SetDocumentSize(uint32_t size) {
+ if (scrollbar_f)
+ scrollbar_f->SetDocumentSize(pp_resource(), size);
+}
+
+void Scrollbar_Dev::SetTickMarks(const Rect* tick_marks, uint32_t count) {
+ if (!scrollbar_f)
+ return;
+
+ std::vector<PP_Rect> temp;
+ temp.resize(count);
+ for (uint32_t i = 0; i < count; ++i)
+ temp[i] = tick_marks[i];
+
+ scrollbar_f->SetTickMarks(pp_resource(), count ? &temp[0] : NULL, count);
+}
+
+void Scrollbar_Dev::ScrollBy(PP_ScrollBy_Dev unit, int32_t multiplier) {
+ if (scrollbar_f)
+ scrollbar_f->ScrollBy(pp_resource(), unit, multiplier);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/scrollbar_dev.h b/ppapi/cpp/dev/scrollbar_dev.h
new file mode 100644
index 0000000..0605641
--- /dev/null
+++ b/ppapi/cpp/dev/scrollbar_dev.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_SCROLLBAR_DEV_H_
+#define PPAPI_CPP_DEV_SCROLLBAR_DEV_H_
+
+#include "ppapi/c/dev/ppb_scrollbar_dev.h"
+#include "ppapi/cpp/dev/widget_dev.h"
+
+namespace pp {
+
+class Instance;
+
+// This class allows a plugin to use the browser's scrollbar widget.
+class Scrollbar_Dev : public Widget_Dev {
+ public:
+ // Creates an is_null() Scrollbar object.
+ Scrollbar_Dev() {}
+
+ explicit Scrollbar_Dev(PP_Resource resource);
+ Scrollbar_Dev(const Instance& instance, bool vertical);
+ Scrollbar_Dev(const Scrollbar_Dev& other);
+
+ Scrollbar_Dev& operator=(const Scrollbar_Dev& other);
+ void swap(Scrollbar_Dev& other);
+
+ // PPB_Scrollbar methods:
+ static uint32_t GetThickness();
+ uint32_t GetValue();
+ void SetValue(uint32_t value);
+ void SetDocumentSize(uint32_t size);
+ void SetTickMarks(const Rect* tick_marks, uint32_t count);
+ void ScrollBy(PP_ScrollBy_Dev unit, int32_t multiplier);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_SCROLLBAR_DEV_H_
diff --git a/ppapi/cpp/dev/selection_dev.cc b/ppapi/cpp/dev/selection_dev.cc
new file mode 100644
index 0000000..6f1fcb7
--- /dev/null
+++ b/ppapi/cpp/dev/selection_dev.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 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/dev/selection_dev.h"
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+namespace {
+
+static const char kPPPSelectionInterface[] = PPP_SELECTION_DEV_INTERFACE;
+
+PP_Var GetSelectedText(PP_Instance instance, bool html) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPSelectionInterface);
+ if (!object)
+ return Var().Detach();
+ return static_cast<Selection_Dev*>(object)->GetSelectedText(html).Detach();
+}
+
+const PPP_Selection_Dev ppp_selection = {
+ &GetSelectedText
+};
+
+} // namespace
+
+Selection_Dev::Selection_Dev(Instance* instance)
+ : associated_instance_(instance) {
+ pp::Module::Get()->AddPluginInterface(kPPPSelectionInterface, &ppp_selection);
+ associated_instance_->AddPerInstanceObject(kPPPSelectionInterface, this);
+}
+
+Selection_Dev::~Selection_Dev() {
+ associated_instance_->RemovePerInstanceObject(kPPPSelectionInterface, this);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/selection_dev.h b/ppapi/cpp/dev/selection_dev.h
new file mode 100644
index 0000000..282bdb4
--- /dev/null
+++ b/ppapi/cpp/dev/selection_dev.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_SELECTION_DEV_H_
+#define PPAPI_CPP_DEV_SELECTION_DEV_H_
+
+#include "ppapi/c/dev/ppp_selection_dev.h"
+
+namespace pp {
+
+class Instance;
+class Var;
+
+// This class allows you to associate the PPP_Selection_Dev C-based interface
+// with an object. It registers as the global handler for handling the
+// PPP_Selection_Dev interface that the browser calls.
+//
+// You would typically use this either via inheritance on your instance:
+// class MyInstance : public pp::Instance, public pp::Selection_Dev {
+// class MyInstance() : pp::Selection_Dev(this) {
+// }
+// ...
+// };
+//
+// or by composition:
+// class MySelection : public pp::Selection_Dev {
+// ...
+// };
+//
+// class MyInstance : public pp::Instance {
+// MyInstance() : selection_(this) {
+// }
+//
+// MySelection selection_;
+// };
+class Selection_Dev {
+ public:
+ Selection_Dev(Instance* instance);
+ virtual ~Selection_Dev();
+
+ // PPP_Selection_Dev functions exposed as virtual functions for you to
+ // override.
+ virtual Var GetSelectedText(bool html) = 0;
+
+ private:
+ Instance* associated_instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_SELECTION_DEV_H_
diff --git a/ppapi/cpp/dev/transport_dev.cc b/ppapi/cpp/dev/transport_dev.cc
new file mode 100644
index 0000000..f7eae6b
--- /dev/null
+++ b/ppapi/cpp/dev/transport_dev.cc
@@ -0,0 +1,28 @@
+// Copyright (c) 2010 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/dev/transport_dev.h"
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_Transport_Dev> transport_f(PPB_TRANSPORT_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+Transport_Dev::Transport_Dev(const char* name,
+ const char* proto) {
+ if (transport_f)
+ PassRefFromConstructor(
+ transport_f->CreateTransport(Module::Get()->pp_module(), name, proto));
+}
+
+} // namespace pp
+
diff --git a/ppapi/cpp/dev/transport_dev.h b/ppapi/cpp/dev/transport_dev.h
new file mode 100644
index 0000000..a9b73c2
--- /dev/null
+++ b/ppapi/cpp/dev/transport_dev.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_TRANSPORT_DEV_H_
+#define PPAPI_CPP_DEV_TRANSPORT_DEV_H_
+
+#include "ppapi/c/dev/ppb_transport_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class Transport_Dev : public Resource {
+ public:
+ Transport_Dev() {}
+ Transport_Dev(const char* name, const char* proto);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_TRANSPORT_DEV_H_
+
diff --git a/ppapi/cpp/dev/url_loader_dev.cc b/ppapi/cpp/dev/url_loader_dev.cc
new file mode 100644
index 0000000..5c63f3d
--- /dev/null
+++ b/ppapi/cpp/dev/url_loader_dev.cc
@@ -0,0 +1,115 @@
+// Copyright (c) 2010 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/dev/url_loader_dev.h"
+
+#include "ppapi/c/dev/ppb_url_loader_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/dev/url_request_info_dev.h"
+#include "ppapi/cpp/dev/url_response_info_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_URLLoader_Dev> url_loader_f(PPB_URLLOADER_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+URLLoader_Dev::URLLoader_Dev(PP_Resource resource) : Resource(resource) {
+}
+
+URLLoader_Dev::URLLoader_Dev(const Instance& instance) {
+ if (!url_loader_f)
+ return;
+ PassRefFromConstructor(url_loader_f->Create(instance.pp_instance()));
+}
+
+URLLoader_Dev::URLLoader_Dev(const URLLoader_Dev& other)
+ : Resource(other) {
+}
+
+URLLoader_Dev& URLLoader_Dev::operator=(const URLLoader_Dev& other) {
+ URLLoader_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void URLLoader_Dev::swap(URLLoader_Dev& other) {
+ Resource::swap(other);
+}
+
+int32_t URLLoader_Dev::Open(const URLRequestInfo_Dev& request_info,
+ const CompletionCallback& cc) {
+ if (!url_loader_f)
+ return PP_ERROR_NOINTERFACE;
+ return url_loader_f->Open(pp_resource(), request_info.pp_resource(),
+ cc.pp_completion_callback());
+}
+
+int32_t URLLoader_Dev::FollowRedirect(const CompletionCallback& cc) {
+ if (!url_loader_f)
+ return PP_ERROR_NOINTERFACE;
+ return url_loader_f->FollowRedirect(pp_resource(),
+ cc.pp_completion_callback());
+}
+
+bool URLLoader_Dev::GetUploadProgress(int64_t* bytes_sent,
+ int64_t* total_bytes_to_be_sent) const {
+ if (!url_loader_f)
+ return false;
+ return url_loader_f->GetUploadProgress(
+ pp_resource(),
+ bytes_sent,
+ total_bytes_to_be_sent);
+}
+
+bool URLLoader_Dev::GetDownloadProgress(
+ int64_t* bytes_received,
+ int64_t* total_bytes_to_be_received) const {
+ if (!url_loader_f)
+ return false;
+ return url_loader_f->GetDownloadProgress(
+ pp_resource(),
+ bytes_received,
+ total_bytes_to_be_received);
+}
+
+URLResponseInfo_Dev URLLoader_Dev::GetResponseInfo() const {
+ if (!url_loader_f)
+ return URLResponseInfo_Dev();
+ return URLResponseInfo_Dev(URLResponseInfo_Dev::PassRef(),
+ url_loader_f->GetResponseInfo(pp_resource()));
+}
+
+int32_t URLLoader_Dev::ReadResponseBody(char* buffer,
+ int32_t bytes_to_read,
+ const CompletionCallback& cc) {
+ if (!url_loader_f)
+ return PP_ERROR_NOINTERFACE;
+ return url_loader_f->ReadResponseBody(pp_resource(),
+ buffer,
+ bytes_to_read,
+ cc.pp_completion_callback());
+}
+
+int32_t URLLoader_Dev::FinishStreamingToFile(const CompletionCallback& cc) {
+ if (!url_loader_f)
+ return PP_ERROR_NOINTERFACE;
+ return url_loader_f->FinishStreamingToFile(pp_resource(),
+ cc.pp_completion_callback());
+}
+
+void URLLoader_Dev::Close() {
+ if (!url_loader_f)
+ return;
+ url_loader_f->Close(pp_resource());
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/url_loader_dev.h b/ppapi/cpp/dev/url_loader_dev.h
new file mode 100644
index 0000000..4256c32
--- /dev/null
+++ b/ppapi/cpp/dev/url_loader_dev.h
@@ -0,0 +1,108 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_URL_LOADER_DEV_H_
+#define PPAPI_CPP_DEV_URL_LOADER_DEV_H_
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class CompletionCallback;
+class Instance;
+class URLRequestInfo_Dev;
+class URLResponseInfo_Dev;
+
+// URLLoader provides an API to download URLs.
+//
+// EXAMPLE USAGE:
+//
+// class MyHandler {
+// public:
+// MyHandler(const Instance& instance)
+// : factory_(this),
+// loader_(instance),
+// did_open_(false) {
+// }
+// void ProcessURL(const char* url) {
+// CompletionCallback* cc = NewCallback();
+// int32_t rv = loader_.Open(MakeRequest(url), cc);
+// if (rv != PP_Error_WouldBlock)
+// cc->Run(rv);
+// }
+// private:
+// CompletionCallback* NewCallback() {
+// return factory_.NewCallback(&MyHandler::DidCompleteIO);
+// }
+// URLRequestInfo MakeRequest(const char* url) {
+// URLRequestInfo request;
+// request.SetURL(url);
+// request.SetMethod("GET");
+// request.SetFollowRedirects(true);
+// return request;
+// }
+// void DidCompleteIO(int32_t result) {
+// if (result > 0) {
+// // buf_ now contains 'result' number of bytes from the URL.
+// ProcessBytes(buf_, result);
+// ReadMore();
+// } else if (result == PP_OK && !did_open_) {
+// // Headers are available, and we can start reading the body.
+// did_open_ = true;
+// ProcessResponseInfo(loader_.GetResponseInfo());
+// ReadMore();
+// } else {
+// // Done reading (possibly with an error given by 'result').
+// }
+// }
+// void ReadMore() {
+// CompletionCallback* cc = NewCallback();
+// int32_t rv = fio_.Read(offset_, buf_, sizeof(buf_), cc);
+// if (rv != PP_Error_WouldBlock)
+// cc->Run(rv);
+// }
+// void ProcessResponseInfo(const URLResponseInfo& response_info) {
+// // Read response headers, etc.
+// }
+// void ProcessBytes(const char* bytes, int32_t length) {
+// // Do work ...
+// }
+// pp::CompletionCallbackFactory<MyHandler> factory_;
+// pp::URLLoader loader_;
+// char buf_[4096];
+// bool did_open_;
+// };
+//
+class URLLoader_Dev : public Resource {
+ public:
+ // Creates an is_null() URLLoader object.
+ URLLoader_Dev() {}
+
+ explicit URLLoader_Dev(PP_Resource resource);
+ explicit URLLoader_Dev(const Instance& instance);
+ URLLoader_Dev(const URLLoader_Dev& other);
+
+ URLLoader_Dev& operator=(const URLLoader_Dev& other);
+ void swap(URLLoader_Dev& other);
+
+ // PPB_URLLoader methods:
+ int32_t Open(const URLRequestInfo_Dev& request_info,
+ const CompletionCallback& cc);
+ int32_t FollowRedirect(const CompletionCallback& cc);
+ bool GetUploadProgress(int64_t* bytes_sent,
+ int64_t* total_bytes_to_be_sent) const;
+ bool GetDownloadProgress(int64_t* bytes_received,
+ int64_t* total_bytes_to_be_received) const;
+ URLResponseInfo_Dev GetResponseInfo() const;
+ int32_t ReadResponseBody(char* buffer,
+ int32_t bytes_to_read,
+ const CompletionCallback& cc);
+ int32_t FinishStreamingToFile(const CompletionCallback& cc);
+ void Close();
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_URL_LOADER_DEV_H_
diff --git a/ppapi/cpp/dev/url_request_info_dev.cc b/ppapi/cpp/dev/url_request_info_dev.cc
new file mode 100644
index 0000000..faf975c5
--- /dev/null
+++ b/ppapi/cpp/dev/url_request_info_dev.cc
@@ -0,0 +1,81 @@
+// Copyright (c) 2010 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/dev/url_request_info_dev.h"
+
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_URLRequestInfo_Dev> url_request_info_f(
+ PPB_URLREQUESTINFO_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+URLRequestInfo_Dev::URLRequestInfo_Dev() {
+ if (!url_request_info_f)
+ return;
+ PassRefFromConstructor(
+ url_request_info_f->Create(Module::Get()->pp_module()));
+}
+
+URLRequestInfo_Dev::URLRequestInfo_Dev(const URLRequestInfo_Dev& other)
+ : Resource(other) {
+}
+
+URLRequestInfo_Dev& URLRequestInfo_Dev::operator=(
+ const URLRequestInfo_Dev& other) {
+ URLRequestInfo_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void URLRequestInfo_Dev::swap(URLRequestInfo_Dev& other) {
+ Resource::swap(other);
+}
+
+bool URLRequestInfo_Dev::SetProperty(PP_URLRequestProperty_Dev property,
+ const Var& value) {
+ if (!url_request_info_f)
+ return false;
+ return url_request_info_f->SetProperty(pp_resource(),
+ property,
+ value.pp_var());
+}
+
+bool URLRequestInfo_Dev::AppendDataToBody(const char* data, uint32_t len) {
+ if (!url_request_info_f)
+ return false;
+ return url_request_info_f->AppendDataToBody(pp_resource(), data, len);
+}
+
+bool URLRequestInfo_Dev::AppendFileToBody(
+ const FileRef_Dev& file_ref,
+ PP_Time expected_last_modified_time) {
+ if (!url_request_info_f)
+ return false;
+ return url_request_info_f->AppendFileToBody(pp_resource(),
+ file_ref.pp_resource(),
+ 0,
+ -1,
+ expected_last_modified_time);
+}
+
+bool URLRequestInfo_Dev::AppendFileRangeToBody(
+ const FileRef_Dev& file_ref,
+ int64_t start_offset,
+ int64_t length,
+ PP_Time expected_last_modified_time) {
+ return url_request_info_f->AppendFileToBody(pp_resource(),
+ file_ref.pp_resource(),
+ start_offset,
+ length,
+ expected_last_modified_time);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/url_request_info_dev.h b/ppapi/cpp/dev/url_request_info_dev.h
new file mode 100644
index 0000000..1d56543
--- /dev/null
+++ b/ppapi/cpp/dev/url_request_info_dev.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_URL_REQUEST_INFO_DEV_H_
+#define PPAPI_CPP_DEV_URL_REQUEST_INFO_DEV_H_
+
+#include "ppapi/c/dev/ppb_url_request_info_dev.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+class FileRef_Dev;
+
+class URLRequestInfo_Dev : public Resource {
+ public:
+ URLRequestInfo_Dev();
+ URLRequestInfo_Dev(const URLRequestInfo_Dev& other);
+
+ URLRequestInfo_Dev& operator=(const URLRequestInfo_Dev& other);
+ void swap(URLRequestInfo_Dev& other);
+
+ // PPB_URLRequestInfo_Dev methods:
+ bool SetProperty(PP_URLRequestProperty_Dev property, const Var& value);
+ bool AppendDataToBody(const char* data, uint32_t len);
+ bool AppendFileToBody(const FileRef_Dev& file_ref,
+ PP_Time expected_last_modified_time = 0);
+ bool AppendFileRangeToBody(const FileRef_Dev& file_ref,
+ int64_t start_offset,
+ int64_t length,
+ PP_Time expected_last_modified_time = 0);
+
+ // Convenient helpers for setting properties:
+ bool SetURL(const Var& url_string) {
+ return SetProperty(PP_URLREQUESTPROPERTY_URL, url_string);
+ }
+ bool SetMethod(const Var& method_string) {
+ return SetProperty(PP_URLREQUESTPROPERTY_METHOD, method_string);
+ }
+ bool SetHeaders(const Var& headers_string) {
+ return SetProperty(PP_URLREQUESTPROPERTY_HEADERS, headers_string);
+ }
+ bool SetStreamToFile(bool enable) {
+ return SetProperty(PP_URLREQUESTPROPERTY_STREAMTOFILE, enable);
+ }
+ bool SetFollowRedirects(bool enable) {
+ return SetProperty(PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS, enable);
+ }
+ bool SetRecordUploadProgress(bool enable) {
+ return SetProperty(PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS, enable);
+ }
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_URL_REQUEST_INFO_DEV_H_
diff --git a/ppapi/cpp/dev/url_response_info_dev.cc b/ppapi/cpp/dev/url_response_info_dev.cc
new file mode 100644
index 0000000..abeca7f
--- /dev/null
+++ b/ppapi/cpp/dev/url_response_info_dev.cc
@@ -0,0 +1,54 @@
+// Copyright (c) 2010 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/dev/url_response_info_dev.h"
+
+#include "ppapi/cpp/dev/file_ref_dev.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_URLResponseInfo_Dev> url_response_info_f(
+ PPB_URLRESPONSEINFO_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+URLResponseInfo_Dev::URLResponseInfo_Dev(const URLResponseInfo_Dev& other)
+ : Resource(other) {
+}
+
+URLResponseInfo_Dev::URLResponseInfo_Dev(PassRef, PP_Resource resource) {
+ PassRefFromConstructor(resource);
+}
+
+URLResponseInfo_Dev& URLResponseInfo_Dev::operator=(
+ const URLResponseInfo_Dev& other) {
+ URLResponseInfo_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void URLResponseInfo_Dev::swap(URLResponseInfo_Dev& other) {
+ Resource::swap(other);
+}
+
+Var URLResponseInfo_Dev::GetProperty(
+ PP_URLResponseProperty_Dev property) const {
+ if (!url_response_info_f)
+ return Var();
+ return Var(Var::PassRef(),
+ url_response_info_f->GetProperty(pp_resource(), property));
+}
+
+FileRef_Dev URLResponseInfo_Dev::GetBody() const {
+ if (!url_response_info_f)
+ return FileRef_Dev();
+ return FileRef_Dev(FileRef_Dev::PassRef(),
+ url_response_info_f->GetBody(pp_resource()));
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/url_response_info_dev.h b/ppapi/cpp/dev/url_response_info_dev.h
new file mode 100644
index 0000000..6596c8b
--- /dev/null
+++ b/ppapi/cpp/dev/url_response_info_dev.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_URL_RESPONSE_INFO_DEV_H_
+#define PPAPI_CPP_DEV_URL_RESPONSE_INFO_DEV_H_
+
+#include "ppapi/c/dev/ppb_url_response_info_dev.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+class FileRef_Dev;
+
+class URLResponseInfo_Dev : public Resource {
+ public:
+ // Creates an is_null() URLResponseInfo object.
+ URLResponseInfo_Dev() {}
+
+ // This constructor is used when we've gotten a PP_Resource as a return value
+ // that has already been addref'ed for us.
+ struct PassRef {};
+ URLResponseInfo_Dev(PassRef, PP_Resource resource);
+
+ URLResponseInfo_Dev(const URLResponseInfo_Dev& other);
+
+ URLResponseInfo_Dev& operator=(const URLResponseInfo_Dev& other);
+ void swap(URLResponseInfo_Dev& other);
+
+ // PPB_URLResponseInfo methods:
+ Var GetProperty(PP_URLResponseProperty_Dev property) const;
+ FileRef_Dev GetBody() const;
+
+ // Convenient helpers for getting properties:
+ Var GetURL() const {
+ return GetProperty(PP_URLRESPONSEPROPERTY_URL);
+ }
+ Var GetRedirectURL() const {
+ return GetProperty(PP_URLRESPONSEPROPERTY_REDIRECTURL);
+ }
+ Var GetRedirectMethod() const {
+ return GetProperty(PP_URLRESPONSEPROPERTY_REDIRECTMETHOD);
+ }
+ int32_t GetStatusCode() const {
+ return GetProperty(PP_URLRESPONSEPROPERTY_STATUSCODE).AsInt();
+ }
+ Var GetStatusLine() const {
+ return GetProperty(PP_URLRESPONSEPROPERTY_STATUSLINE);
+ }
+ Var GetHeaders() const {
+ return GetProperty(PP_URLRESPONSEPROPERTY_HEADERS);
+ }
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_URL_RESPONSE_INFO_DEV_H_
diff --git a/ppapi/cpp/dev/url_util_dev.cc b/ppapi/cpp/dev/url_util_dev.cc
new file mode 100644
index 0000000..82e1974
--- /dev/null
+++ b/ppapi/cpp/dev/url_util_dev.cc
@@ -0,0 +1,70 @@
+// Copyright (c) 2010 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/dev/url_util_dev.h"
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+
+namespace pp {
+
+// static
+const UrlUtil_Dev* UrlUtil_Dev::Get() {
+ static bool tried_to_init = false;
+ static UrlUtil_Dev util;
+
+ if (!tried_to_init) {
+ tried_to_init = true;
+ util.interface_ = static_cast<const PPB_UrlUtil_Dev*>(
+ Module::Get()->GetBrowserInterface(PPB_URLUTIL_DEV_INTERFACE));
+ }
+
+ if (!util.interface_)
+ return NULL;
+ return &util;
+}
+
+Var UrlUtil_Dev::Canonicalize(const Var& url,
+ PP_UrlComponents_Dev* components) const {
+ return Var(Var::PassRef(),
+ interface_->Canonicalize(url.pp_var(), components));
+}
+
+Var UrlUtil_Dev::ResolveRelativeToUrl(const Var& base_url,
+ const Var& relative_string,
+ PP_UrlComponents_Dev* components) const {
+ return Var(Var::PassRef(),
+ interface_->ResolveRelativeToUrl(base_url.pp_var(),
+ relative_string.pp_var(),
+ components));
+}
+
+Var UrlUtil_Dev::ResoveRelativeToDocument(
+ const Instance& instance,
+ const Var& relative_string,
+ PP_UrlComponents_Dev* components) const {
+ return Var(Var::PassRef(),
+ interface_->ResolveRelativeToDocument(instance.pp_instance(),
+ relative_string.pp_var(),
+ components));
+}
+
+bool UrlUtil_Dev::IsSameSecurityOrigin(const Var& url_a,
+ const Var& url_b) const {
+ return interface_->IsSameSecurityOrigin(url_a.pp_var(), url_b.pp_var());
+}
+
+bool UrlUtil_Dev::DocumentCanRequest(const Instance& instance,
+ const Var& url) const {
+ return interface_->DocumentCanRequest(instance.pp_instance(), url.pp_var());
+}
+
+bool UrlUtil_Dev::DocumentCanAccessDocument(const Instance& active,
+ const Instance& target) const {
+ return interface_->DocumentCanAccessDocument(active.pp_instance(),
+ target.pp_instance());
+}
+
+} // namespace pp
+
diff --git a/ppapi/cpp/dev/url_util_dev.h b/ppapi/cpp/dev/url_util_dev.h
new file mode 100644
index 0000000..3be217e
--- /dev/null
+++ b/ppapi/cpp/dev/url_util_dev.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_URL_UTIL_DEV_H_
+#define PPAPI_CPP_DEV_URL_UTIL_DEV_H_
+
+#include "ppapi/c/dev/ppb_url_util_dev.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+class Instance;
+class Module;
+
+// Simple wrapper around the PPB_UrlUtil interface.
+class UrlUtil_Dev {
+ public:
+ // This class is just a collection of random functions that aren't
+ // particularly attached to anything. So this getter returns a cached
+ // instance of this interface. This may return NULL if the browser doesn't
+ // support the UrlUtil inteface. Since this is a singleton, don't delete the
+ // pointer.
+ static const UrlUtil_Dev* Get();
+
+ Var Canonicalize(const Var& url,
+ PP_UrlComponents_Dev* components = NULL) const;
+
+ Var ResolveRelativeToUrl(const Var& base_url,
+ const Var& relative_string,
+ PP_UrlComponents_Dev* components = NULL) const;
+ Var ResoveRelativeToDocument(const Instance& instance,
+ const Var& relative_string,
+ PP_UrlComponents_Dev* components = NULL) const;
+
+ bool IsSameSecurityOrigin(const Var& url_a, const Var& url_b) const;
+ bool DocumentCanRequest(const Instance& instance, const Var& url) const;
+ bool DocumentCanAccessDocument(const Instance& active,
+ const Instance& target) const;
+
+ private:
+ UrlUtil_Dev() : interface_(NULL) {}
+
+ // Copy and assignment are disallowed.
+ UrlUtil_Dev(const UrlUtil_Dev& other);
+ UrlUtil_Dev& operator=(const UrlUtil_Dev& other);
+
+ const PPB_UrlUtil_Dev* interface_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_URL_UTIL_DEV_H_
+
diff --git a/ppapi/cpp/dev/video_decoder_dev.cc b/ppapi/cpp/dev/video_decoder_dev.cc
new file mode 100644
index 0000000..298bad4
--- /dev/null
+++ b/ppapi/cpp/dev/video_decoder_dev.cc
@@ -0,0 +1,84 @@
+// Copyright (c) 2010 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/dev/video_decoder_dev.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_VideoDecoder_Dev> video_decoder_f(
+ PPB_VIDEODECODER_DEV_INTERFACE);
+
+} // namespace
+
+
+namespace pp {
+
+VideoDecoder_Dev::VideoDecoder_Dev(PP_Resource resource) : Resource(resource) {
+}
+
+VideoDecoder_Dev::VideoDecoder_Dev(
+ const Instance& instance,
+ const PP_VideoDecoderConfig_Dev& decoder_config) {
+ if (!video_decoder_f)
+ return;
+ PassRefFromConstructor(video_decoder_f->Create(instance.pp_instance(),
+ &decoder_config));
+}
+
+VideoDecoder_Dev::VideoDecoder_Dev(const VideoDecoder_Dev& other)
+ : Resource(other) {
+}
+
+VideoDecoder_Dev& VideoDecoder_Dev::operator=(const VideoDecoder_Dev& other) {
+ VideoDecoder_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void VideoDecoder_Dev::swap(VideoDecoder_Dev& other) {
+ Resource::swap(other);
+}
+
+// static
+bool VideoDecoder_Dev::GetConfig(const Instance& instance,
+ PP_VideoCodecId_Dev codec,
+ PP_VideoConfig_Dev* configs,
+ int32_t config_size,
+ int32_t* num_config) {
+ if (!video_decoder_f)
+ return false;
+ return video_decoder_f->GetConfig(instance.pp_instance(),
+ codec,
+ configs,
+ config_size,
+ num_config);
+}
+
+bool VideoDecoder_Dev::Decode(PP_VideoCompressedDataBuffer_Dev& input_buffer) {
+ if (!video_decoder_f || !pp_resource())
+ return false;
+ return video_decoder_f->Decode(pp_resource(),
+ &input_buffer);
+}
+
+int32_t VideoDecoder_Dev::Flush(PP_CompletionCallback callback) {
+ if (!video_decoder_f)
+ return PP_ERROR_NOINTERFACE;
+ return video_decoder_f->Flush(pp_resource(), callback);
+}
+
+bool VideoDecoder_Dev::ReturnUncompressedDataBuffer(
+ PP_VideoUncompressedDataBuffer_Dev& buffer) {
+ if (!video_decoder_f || !pp_resource())
+ return false;
+ return video_decoder_f->ReturnUncompressedDataBuffer(pp_resource(),
+ &buffer);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/video_decoder_dev.h b/ppapi/cpp/dev/video_decoder_dev.h
new file mode 100644
index 0000000..0ee6fc96
--- /dev/null
+++ b/ppapi/cpp/dev/video_decoder_dev.h
@@ -0,0 +1,47 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_VIDEO_DECODER_DEV_H_
+#define PPAPI_CPP_DEV_VIDEO_DECODER_DEV_H_
+
+#include "ppapi/c/dev/pp_video_dev.h"
+#include "ppapi/c/dev/ppb_video_decoder_dev.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class Instance;
+
+// Provides access to video decoders.
+class VideoDecoder_Dev : public Resource {
+ public:
+ // Creates an is_null() VideoDecoder object.
+ VideoDecoder_Dev() {}
+
+ explicit VideoDecoder_Dev(PP_Resource resource);
+
+ VideoDecoder_Dev(const Instance& instance,
+ const PP_VideoDecoderConfig_Dev& decoder_config);
+ VideoDecoder_Dev(const VideoDecoder_Dev& other);
+
+ VideoDecoder_Dev& operator=(const VideoDecoder_Dev& other);
+ void swap(VideoDecoder_Dev& other);
+
+ // PPB_VideoDecoder methods:
+ static bool GetConfig(const Instance& instance,
+ PP_VideoCodecId_Dev codec,
+ PP_VideoConfig_Dev* configs,
+ int32_t config_size,
+ int32_t* num_config);
+
+ bool Decode(PP_VideoCompressedDataBuffer_Dev& input_buffer);
+
+ int32_t Flush(PP_CompletionCallback callback);
+
+ bool ReturnUncompressedDataBuffer(PP_VideoUncompressedDataBuffer_Dev& buffer);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_VIDEO_DECODER_DEV_H_
diff --git a/ppapi/cpp/dev/widget_client_dev.cc b/ppapi/cpp/dev/widget_client_dev.cc
new file mode 100644
index 0000000..8407810
--- /dev/null
+++ b/ppapi/cpp/dev/widget_client_dev.cc
@@ -0,0 +1,74 @@
+// Copyright (c) 2010 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/dev/widget_client_dev.h"
+
+#include "ppapi/c/dev/ppp_scrollbar_dev.h"
+#include "ppapi/c/dev/ppp_widget_dev.h"
+#include "ppapi/cpp/dev/scrollbar_dev.h"
+#include "ppapi/cpp/dev/widget_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+#include "ppapi/cpp/rect.h"
+
+namespace pp {
+
+namespace {
+
+// PPP_Widget_Dev --------------------------------------------------------------
+
+const char kPPPWidgetInterface[] = PPP_WIDGET_DEV_INTERFACE;
+
+void Widget_Invalidate(PP_Instance instance,
+ PP_Resource widget_id,
+ const PP_Rect* dirty_rect) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPWidgetInterface);
+ if (!object)
+ return;
+ return static_cast<WidgetClient_Dev*>(object)->InvalidateWidget(
+ Widget_Dev(widget_id), *dirty_rect);
+}
+
+static PPP_Widget_Dev widget_interface = {
+ &Widget_Invalidate,
+};
+
+// PPP_Scrollbar_Dev -----------------------------------------------------------
+
+const char kPPPScrollbarInterface[] = PPP_SCROLLBAR_DEV_INTERFACE;
+
+void Scrollbar_ValueChanged(PP_Instance instance,
+ PP_Resource scrollbar_id,
+ uint32_t value) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPScrollbarInterface);
+ if (!object)
+ return;
+ return static_cast<WidgetClient_Dev*>(object)->ScrollbarValueChanged(
+ Scrollbar_Dev(scrollbar_id), value);
+}
+
+static PPP_Scrollbar_Dev scrollbar_interface = {
+ &Scrollbar_ValueChanged,
+};
+
+} // namespace
+
+WidgetClient_Dev::WidgetClient_Dev(Instance* instance)
+ : associated_instance_(instance) {
+ pp::Module::Get()->AddPluginInterface(kPPPWidgetInterface, &widget_interface);
+ associated_instance_->AddPerInstanceObject(kPPPWidgetInterface, this);
+ pp::Module::Get()->AddPluginInterface(kPPPScrollbarInterface,
+ &scrollbar_interface);
+ associated_instance_->AddPerInstanceObject(kPPPScrollbarInterface, this);
+}
+
+WidgetClient_Dev::~WidgetClient_Dev() {
+ associated_instance_->RemovePerInstanceObject(kPPPScrollbarInterface, this);
+ associated_instance_->RemovePerInstanceObject(kPPPWidgetInterface, this);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/widget_client_dev.h b/ppapi/cpp/dev/widget_client_dev.h
new file mode 100644
index 0000000..a8910e8
--- /dev/null
+++ b/ppapi/cpp/dev/widget_client_dev.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_WIDGET_CLIENT_DEV_H_
+#define PPAPI_CPP_DEV_WIDGET_CLIENT_DEV_H_
+
+#include "ppapi/c/pp_stdint.h"
+
+namespace pp {
+
+class Instance;
+class Rect;
+class Scrollbar_Dev;
+class Widget_Dev;
+
+// This class provides a C++ interface for callbacks related to widgets. You
+// would normally use multiple inheritance to derive from this class in your
+// instance.
+class WidgetClient_Dev {
+ public:
+ WidgetClient_Dev(Instance* instance);
+ virtual ~WidgetClient_Dev();
+
+ /**
+ * Notification that the given widget should be repainted. This is the
+ * implementation for PPP_Widget_Dev.
+ */
+ virtual void InvalidateWidget(Widget_Dev widget, const Rect& dirty_rect) = 0;
+
+ /**
+ * Notification that the given scrollbar should change value. This is the
+ * implementation for PPP_Scrollbar_Dev.
+ */
+ virtual void ScrollbarValueChanged(Scrollbar_Dev scrollbar,
+ uint32_t value) = 0;
+
+ private:
+ Instance* associated_instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_WIDGET_CLIENT_DEV_H_
diff --git a/ppapi/cpp/dev/widget_dev.cc b/ppapi/cpp/dev/widget_dev.cc
new file mode 100644
index 0000000..e3c94ee
--- /dev/null
+++ b/ppapi/cpp/dev/widget_dev.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2010 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/dev/widget_dev.h"
+
+#include "ppapi/c/dev/ppb_widget_dev.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_Widget_Dev> widget_f(PPB_WIDGET_DEV_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+Widget_Dev::Widget_Dev(PP_Resource resource) : Resource(resource) {
+}
+
+Widget_Dev::Widget_Dev(const Widget_Dev& other) : Resource(other) {
+}
+
+Widget_Dev& Widget_Dev::operator=(const Widget_Dev& other) {
+ Widget_Dev copy(other);
+ swap(copy);
+ return *this;
+}
+
+void Widget_Dev::swap(Widget_Dev& other) {
+ Resource::swap(other);
+}
+
+bool Widget_Dev::Paint(const Rect& rect, ImageData* image) {
+ if (!widget_f)
+ return false;
+ return widget_f->Paint(
+ pp_resource(), &rect.pp_rect(), image->pp_resource());
+}
+
+bool Widget_Dev::HandleEvent(const PP_InputEvent& event) {
+ if (!widget_f)
+ return false;
+ return widget_f->HandleEvent(pp_resource(), &event);
+}
+
+bool Widget_Dev::GetLocation(Rect* location) {
+ if (!widget_f)
+ return false;
+ return widget_f->GetLocation(pp_resource(), &location->pp_rect());
+}
+
+void Widget_Dev::SetLocation(const Rect& location) {
+ if (widget_f)
+ widget_f->SetLocation(pp_resource(), &location.pp_rect());
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/widget_dev.h b/ppapi/cpp/dev/widget_dev.h
new file mode 100644
index 0000000..59ca60d
--- /dev/null
+++ b/ppapi/cpp/dev/widget_dev.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_WIDGET_DEV_H_
+#define PPAPI_CPP_DEV_WIDGET_DEV_H_
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/cpp/resource.h"
+
+struct PP_InputEvent;
+
+namespace pp {
+
+class ImageData;
+class Instance;
+class Rect;
+
+// This is the base class for widget elements. As such, it can't be created
+// directly.
+class Widget_Dev : public Resource {
+ public:
+ // Creates an is_null() Widget object.
+ Widget_Dev() {}
+
+ explicit Widget_Dev(PP_Resource resource);
+ Widget_Dev(const Widget_Dev& other);
+
+ Widget_Dev& operator=(const Widget_Dev& other);
+ void swap(Widget_Dev& other);
+
+ // PPB_Widget methods:
+ bool Paint(const Rect& rect, ImageData* image);
+ bool HandleEvent(const PP_InputEvent& event);
+ bool GetLocation(Rect* location);
+ void SetLocation(const Rect& location);
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_WIDGET_DEV_H_
diff --git a/ppapi/cpp/dev/zoom_dev.cc b/ppapi/cpp/dev/zoom_dev.cc
new file mode 100644
index 0000000..43966b3
--- /dev/null
+++ b/ppapi/cpp/dev/zoom_dev.cc
@@ -0,0 +1,58 @@
+// Copyright (c) 2010 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/dev/zoom_dev.h"
+
+#include "ppapi/c/dev/ppb_zoom_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace pp {
+
+namespace {
+
+static const char kPPPZoomInterface[] = PPP_ZOOM_DEV_INTERFACE;
+
+void Zoom(PP_Instance instance,
+ double factor,
+ bool text_only) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPZoomInterface);
+ if (!object)
+ return;
+ static_cast<Zoom_Dev*>(object)->Zoom(factor, text_only);
+}
+
+const PPP_Zoom_Dev ppp_zoom = {
+ &Zoom
+};
+
+DeviceFuncs<PPB_Zoom_Dev> ppb_zoom_f(PPB_ZOOM_DEV_INTERFACE);
+
+} // namespace
+
+Zoom_Dev::Zoom_Dev(Instance* instance) : associated_instance_(instance) {
+ pp::Module::Get()->AddPluginInterface(kPPPZoomInterface, &ppp_zoom);
+ associated_instance_->AddPerInstanceObject(kPPPZoomInterface, this);
+}
+
+Zoom_Dev::~Zoom_Dev() {
+ associated_instance_->RemovePerInstanceObject(kPPPZoomInterface, this);
+}
+
+void Zoom_Dev::ZoomChanged(double factor) {
+ if (ppb_zoom_f)
+ ppb_zoom_f->ZoomChanged(associated_instance_->pp_instance(), factor);
+}
+
+void Zoom_Dev::ZoomLimitsChanged(double minimum_factor,
+ double maximium_factor) {
+ if (!ppb_zoom_f)
+ return;
+ ppb_zoom_f->ZoomLimitsChanged(
+ associated_instance_->pp_instance(), minimum_factor, maximium_factor);
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/dev/zoom_dev.h b/ppapi/cpp/dev/zoom_dev.h
new file mode 100644
index 0000000..0a079f0
--- /dev/null
+++ b/ppapi/cpp/dev/zoom_dev.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_DEV_ZOOM_DEV_H_
+#define PPAPI_CPP_DEV_ZOOM_DEV_H_
+
+#include <string>
+
+#include "ppapi/c/dev/ppp_zoom_dev.h"
+
+namespace pp {
+
+class Instance;
+
+// This class allows you to associate the PPP_Zoom_Dev and PPB_Zoom_Dev C-based
+// interfaces with an object. It associates itself with the given instance, and
+// registers as the global handler for handling the PPP_Zoom_Dev interface that
+// the browser calls.
+//
+// You would typically use this either via inheritance on your instance:
+// class MyInstance : public pp::Instance, public pp::Zoom_Dev {
+// class MyInstance() : pp::Zoom_Dev(this) {
+// }
+// ...
+// };
+//
+// or by composition:
+// class MyZoom : public pp::Zoom_Dev {
+// ...
+// };
+//
+// class MyInstance : public pp::Instance {
+// MyInstance() : zoom_(this) {
+// }
+//
+// MyZoom zoom_;
+// };
+class Zoom_Dev {
+ public:
+ Zoom_Dev(Instance* instance);
+ virtual ~Zoom_Dev();
+
+ // PPP_Zoom_Dev functions exposed as virtual functions for you to
+ // override.
+ virtual void Zoom(double factor, bool text_only) = 0;
+
+ // PPB_Zoom_Def functions for you to call to report new zoom factor.
+ void ZoomChanged(double factor);
+ void ZoomLimitsChanged(double minimum_factor, double maximium_factor);
+
+ private:
+ Instance* associated_instance_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_DEV_ZOOM_DEV_H_
diff --git a/ppapi/cpp/graphics_2d.cc b/ppapi/cpp/graphics_2d.cc
new file mode 100644
index 0000000..aaccff7
--- /dev/null
+++ b/ppapi/cpp/graphics_2d.cc
@@ -0,0 +1,98 @@
+// Copyright (c) 2010 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/graphics_2d.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/ppb_graphics_2d.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+#include "ppapi/cpp/point.h"
+#include "ppapi/cpp/rect.h"
+
+namespace {
+
+DeviceFuncs<PPB_Graphics2D> graphics_2d_f(PPB_GRAPHICS_2D_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+Graphics2D::Graphics2D() : Resource() {
+}
+
+Graphics2D::Graphics2D(const Graphics2D& other)
+ : Resource(other),
+ size_(other.size_) {
+}
+
+Graphics2D::Graphics2D(const Size& size, bool is_always_opaque)
+ : Resource() {
+ if (!graphics_2d_f)
+ return;
+ PassRefFromConstructor(graphics_2d_f->Create(Module::Get()->pp_module(),
+ &size.pp_size(),
+ is_always_opaque));
+ if (!is_null()) {
+ // Only save the size if allocation succeeded.
+ size_ = size;
+ }
+}
+
+Graphics2D::~Graphics2D() {
+}
+
+Graphics2D& Graphics2D::operator=(const Graphics2D& other) {
+ Graphics2D copy(other);
+ swap(copy);
+ return *this;
+}
+
+void Graphics2D::swap(Graphics2D& other) {
+ Resource::swap(other);
+ size_.swap(other.size_);
+}
+
+void Graphics2D::PaintImageData(const ImageData& image,
+ const Point& top_left) {
+ if (!graphics_2d_f)
+ return;
+ graphics_2d_f->PaintImageData(pp_resource(), image.pp_resource(),
+ &top_left.pp_point(), NULL);
+}
+
+void Graphics2D::PaintImageData(const ImageData& image,
+ const Point& top_left,
+ const Rect& src_rect) {
+ if (!graphics_2d_f)
+ return;
+ graphics_2d_f->PaintImageData(pp_resource(), image.pp_resource(),
+ &top_left.pp_point(), &src_rect.pp_rect());
+}
+
+void Graphics2D::Scroll(const Rect& clip, const Point& amount) {
+ if (!graphics_2d_f)
+ return;
+ graphics_2d_f->Scroll(pp_resource(), &clip.pp_rect(), &amount.pp_point());
+}
+
+void Graphics2D::ReplaceContents(ImageData* image) {
+ if (!graphics_2d_f)
+ return;
+ graphics_2d_f->ReplaceContents(pp_resource(), image->pp_resource());
+
+ // On success, reset the image data. This is to help prevent people
+ // from continuing to use the resource which will result in artifacts.
+ *image = ImageData();
+}
+
+int32_t Graphics2D::Flush(const CompletionCallback& cc) {
+ if (!graphics_2d_f)
+ return PP_ERROR_NOINTERFACE;
+ return graphics_2d_f->Flush(pp_resource(), cc.pp_completion_callback());
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/graphics_2d.h b/ppapi/cpp/graphics_2d.h
new file mode 100644
index 0000000..8f4622f
--- /dev/null
+++ b/ppapi/cpp/graphics_2d.h
@@ -0,0 +1,75 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_GRAPHICS_2D_H_
+#define PPAPI_CPP_GRAPHICS_2D_H_
+
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/size.h"
+
+namespace pp {
+
+class CompletionCallback;
+class ImageData;
+class Point;
+class Rect;
+
+class Graphics2D : public Resource {
+ public:
+ // Creates an is_null() ImageData object.
+ Graphics2D();
+
+ // The copied context will refer to the original (since this is just a wrapper
+ // around a refcounted resource).
+ Graphics2D(const Graphics2D& other);
+
+ // Allocates a new 2D graphics context with the given size in the browser,
+ // resulting object will be is_null() if the allocation failed.
+ Graphics2D(const Size& size, bool is_always_opaque);
+
+ virtual ~Graphics2D();
+
+ Graphics2D& operator=(const Graphics2D& other);
+ void swap(Graphics2D& other);
+
+ const Size& size() const { return size_; }
+
+ // Enqueues paint or scroll commands. THIS COMMAND HAS NO EFFECT UNTIL YOU
+ // CALL Flush().
+ //
+ // If you call the version with no source rect, the entire image will be
+ // painted.
+ //
+ // Please see PPB_Graphics2D.PaintImageData / .Scroll for more details.
+ void PaintImageData(const ImageData& image,
+ const Point& top_left);
+ void PaintImageData(const ImageData& image,
+ const Point& top_left,
+ const Rect& src_rect);
+ void Scroll(const Rect& clip, const Point& amount);
+
+ // The browser will take ownership of the given image data. The object
+ // pointed to by the parameter will be cleared. To avoid horrible artifacts,
+ // you should also not use any other ImageData objects referring to the same
+ // resource will no longer be usable. THIS COMMAND HAS NO EFFECT UNTIL YOU
+ // CALL Flush().
+ //
+ // Please see PPB_Graphics2D.ReplaceContents for more details.
+ void ReplaceContents(ImageData* image);
+
+ // Flushes all the currently enqueued Paint, Scroll, and Replace commands.
+ // Can be used in synchronous mode (NULL callback pointer) from background
+ // threads.
+ //
+ // Please see PPB_Graphics2D.Flush for more details.
+ int32_t Flush(const CompletionCallback& cc);
+
+ private:
+ Size size_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_GRAPHICS_2D_H_
diff --git a/ppapi/cpp/image_data.cc b/ppapi/cpp/image_data.cc
new file mode 100644
index 0000000..6f4bf69
--- /dev/null
+++ b/ppapi/cpp/image_data.cc
@@ -0,0 +1,98 @@
+// Copyright (c) 2010 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/image_data.h"
+
+#include <string.h> // Needed for memset.
+
+#include <algorithm>
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+
+namespace {
+
+DeviceFuncs<PPB_ImageData> image_data_f(PPB_IMAGEDATA_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+ImageData::ImageData() : data_(NULL) {
+ memset(&desc_, 0, sizeof(PP_ImageDataDesc));
+}
+
+ImageData::ImageData(const ImageData& other)
+ : Resource(other),
+ desc_(other.desc_),
+ data_(other.data_) {
+}
+
+ImageData::ImageData(PassRef, PP_Resource resource)
+ : data_(NULL) {
+ memset(&desc_, 0, sizeof(PP_ImageDataDesc));
+
+ if (!image_data_f)
+ return;
+
+ PassRefAndInitData(resource);
+}
+
+ImageData::ImageData(PP_ImageDataFormat format,
+ const Size& size,
+ bool init_to_zero)
+ : data_(NULL) {
+ memset(&desc_, 0, sizeof(PP_ImageDataDesc));
+
+ if (!image_data_f)
+ return;
+
+ PassRefAndInitData(image_data_f->Create(Module::Get()->pp_module(),
+ format, &size.pp_size(),
+ init_to_zero));
+}
+
+ImageData::~ImageData() {
+}
+
+ImageData& ImageData::operator=(const ImageData& other) {
+ ImageData copy(other);
+ swap(copy);
+ return *this;
+}
+
+void ImageData::swap(ImageData& other) {
+ Resource::swap(other);
+ std::swap(desc_, other.desc_);
+ std::swap(data_, other.data_);
+}
+
+const uint32_t* ImageData::GetAddr32(const Point& coord) const {
+ // Prefer evil const casts rather than evil code duplication.
+ return const_cast<ImageData*>(this)->GetAddr32(coord);
+}
+
+uint32_t* ImageData::GetAddr32(const Point& coord) {
+ // If we add more image format types that aren't 32-bit, we'd want to check
+ // here and fail.
+ return reinterpret_cast<uint32_t*>(
+ &static_cast<char*>(data())[coord.y() * stride() + coord.x() * 4]);
+}
+
+// static
+PP_ImageDataFormat ImageData::GetNativeImageDataFormat() {
+ if (!image_data_f)
+ return PP_IMAGEDATAFORMAT_BGRA_PREMUL; // Default to something on failure.
+ return image_data_f->GetNativeImageDataFormat();
+}
+
+void ImageData::PassRefAndInitData(PP_Resource resource) {
+ PassRefFromConstructor(resource);
+ if (!image_data_f->Describe(pp_resource(), &desc_) ||
+ !(data_ = image_data_f->Map(pp_resource())))
+ *this = ImageData();
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/image_data.h b/ppapi/cpp/image_data.h
new file mode 100644
index 0000000..07b77e3
--- /dev/null
+++ b/ppapi/cpp/image_data.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_IMAGE_DATA_H_
+#define PPAPI_CPP_IMAGE_DATA_H_
+
+#include "ppapi/c/ppb_image_data.h"
+#include "ppapi/cpp/point.h"
+#include "ppapi/cpp/size.h"
+#include "ppapi/cpp/resource.h"
+
+namespace pp {
+
+class Plugin;
+
+class ImageData : public Resource {
+ public:
+ // Creates an is_null() ImageData object.
+ ImageData();
+
+ // This magic constructor is used when we've gotten a PP_Resource as a return
+ // value that has already been addref'ed for us.
+ struct PassRef {};
+ ImageData(PassRef, PP_Resource resource);
+
+ ImageData(const ImageData& other);
+
+ // Allocates a new ImageData in the browser with the given parameters. The
+ // resulting object will be is_null() if the allocation failed.
+ ImageData(PP_ImageDataFormat format,
+ const Size& size,
+ bool init_to_zero);
+
+ virtual ~ImageData();
+
+ ImageData& operator=(const ImageData& other);
+ void swap(ImageData& other);
+
+ // Returns the browser's preferred format for images. Using this format
+ // guarantees no extra conversions will occur when painting.
+ static PP_ImageDataFormat GetNativeImageDataFormat();
+
+ PP_ImageDataFormat format() const { return desc_.format; }
+
+ pp::Size size() const { return desc_.size; }
+ int32_t stride() const { return desc_.stride; }
+
+ void* data() const { return data_; }
+
+ // Helper function to retrieve the address of the given pixel for 32-bit
+ // pixel formats.
+ const uint32_t* GetAddr32(const Point& coord) const;
+ uint32_t* GetAddr32(const Point& coord);
+
+ private:
+ void PassRefAndInitData(PP_Resource resource);
+
+ PP_ImageDataDesc desc_;
+ void* data_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_IMAGE_DATA_H_
diff --git a/ppapi/cpp/instance.cc b/ppapi/cpp/instance.cc
new file mode 100644
index 0000000..16d7f76
--- /dev/null
+++ b/ppapi/cpp/instance.cc
@@ -0,0 +1,143 @@
+// Copyright (c) 2010 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/dev/ppp_printing_dev.h"
+#include "ppapi/c/ppb_instance.h"
+#include "ppapi/cpp/dev/scrollbar_dev.h"
+#include "ppapi/cpp/dev/widget_dev.h"
+#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/logging.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"
+
+namespace {
+
+DeviceFuncs<PPB_Instance> ppb_instance_f(PPB_INSTANCE_INTERFACE);
+
+} // namespace
+
+namespace pp {
+
+Instance::Instance(PP_Instance instance) : pp_instance_(instance) {
+}
+
+Instance::~Instance() {
+ // Ensure that all per-instance objects have been removed. Generally, these
+ // objects should have their lifetime scoped to the instance, such as being
+ // instance members or even implemented by your instance sub-class directly.
+ //
+ // If they're not unregistered at this point, they will usually have a
+ // dangling reference to the instance, which can cause a crash later.
+ PP_DCHECK(interface_name_to_objects_.empty());
+}
+
+bool Instance::Init(uint32_t /*argc*/, const char* /*argn*/[],
+ const char* /*argv*/[]) {
+ return true;
+}
+
+void Instance::DidChangeView(const pp::Rect& /*position*/,
+ const pp::Rect& /*clip*/) {
+}
+
+void Instance::DidChangeFocus(bool /*has_focus*/) {
+}
+
+
+bool Instance::HandleDocumentLoad(const URLLoader_Dev& /*url_loader*/) {
+ return false;
+}
+
+bool Instance::HandleInputEvent(const PP_InputEvent& /*event*/) {
+ return false;
+}
+
+Var Instance::GetInstanceObject() {
+ return Var();
+}
+
+Var Instance::GetSelectedText(bool /* html */) {
+ return Var();
+}
+
+Var Instance::GetWindowObject() {
+ if (!ppb_instance_f)
+ return Var();
+ return Var(Var::PassRef(), ppb_instance_f->GetWindowObject(pp_instance()));
+}
+
+Var Instance::GetOwnerElementObject() {
+ if (!ppb_instance_f)
+ return Var();
+ return Var(Var::PassRef(),
+ ppb_instance_f->GetOwnerElementObject(pp_instance()));
+}
+
+bool Instance::BindGraphics(const Graphics2D& graphics) {
+ if (!ppb_instance_f)
+ return false;
+ return ppb_instance_f->BindGraphics(pp_instance(), graphics.pp_resource());
+}
+
+bool Instance::IsFullFrame() {
+ if (!ppb_instance_f)
+ return false;
+ return ppb_instance_f->IsFullFrame(pp_instance());
+}
+
+Var Instance::ExecuteScript(const Var& script, Var* exception) {
+ if (!ppb_instance_f)
+ return Var();
+ return Var(Var::PassRef(),
+ ppb_instance_f->ExecuteScript(pp_instance(), script.pp_var(),
+ Var::OutException(exception).get()));
+}
+
+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::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
diff --git a/ppapi/cpp/instance.h b/ppapi/cpp/instance.h
new file mode 100644
index 0000000..df09bb9
--- /dev/null
+++ b/ppapi/cpp/instance.h
@@ -0,0 +1,157 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_INSTANCE_H_
+#define PPAPI_CPP_INSTANCE_H_
+
+/**
+ * @file
+ * Defines the API ...
+ *
+ * @addtogroup CPP
+ * @{
+ */
+
+#include <map>
+#include <string>
+
+#include "ppapi/c/dev/ppp_printing_dev.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_resource.h"
+#include "ppapi/c/pp_stdint.h"
+
+struct PP_InputEvent;
+
+/** The C++ interface to the Pepper API. */
+namespace pp {
+
+class Graphics2D;
+class ImageData;
+class Point;
+class Rect;
+class Rect;
+class Resource;
+class Scrollbar_Dev;
+class URLLoader_Dev;
+class Var;
+class Widget_Dev;
+
+class Instance {
+ public:
+ explicit Instance(PP_Instance instance);
+ virtual ~Instance();
+
+ PP_Instance pp_instance() const { return pp_instance_; }
+
+ /**
+ * Initializes this plugin with the given arguments.
+ * @param argc The argument count
+ * @param argn The argument names
+ * @param argv The argument values
+ * @return True on success. Returning false causes the plugin
+ * instance to be deleted and no other functions to be called.
+ */
+ virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
+
+
+ // @{
+ /** @name PPP_Instance methods for the plugin to override: */
+
+ /** See PPP_Instance.DidChangeView. */
+ virtual void DidChangeView(const Rect& position, const Rect& clip);
+
+ /** See PPP_Instance.DidChangeFocus. */
+ virtual void DidChangeFocus(bool has_focus);
+
+ /** See PPP_Instance.HandleInputEvent. */
+ virtual bool HandleInputEvent(const PP_InputEvent& event);
+
+ /** See PPP_Instance.HandleDocumentLoad. */
+ virtual bool HandleDocumentLoad(const URLLoader_Dev& url_loader);
+
+ /** See PPP_Instance.GetInstanceObject. */
+ virtual Var GetInstanceObject();
+
+ /** See PPP_Instance.GetSelectedText. */
+ virtual Var GetSelectedText(bool html);
+ // @}
+
+ // @{
+ /** @name PPB_Instance methods for querying the browser: */
+
+ /** See PPB_Instance.GetWindowObject. */
+ Var GetWindowObject();
+
+ /** See PPB_Instance.GetOwnerElementObject. */
+ Var GetOwnerElementObject();
+
+ /** See PPB_Instance.BindGraphics. */
+ bool BindGraphics(const Graphics2D& graphics);
+
+ /** See PPB_Instance.IsFullFrame. */
+ bool IsFullFrame();
+
+ /** See PPB_Instance.ExecuteScript. */
+ Var ExecuteScript(const Var& script, Var* exception = NULL);
+ // @}
+
+ /**
+ * Associates a plugin instance with an interface,
+ * creating an object... {PENDING: clarify!}
+ *
+ * Many optional interfaces are associated with a plugin instance. For
+ * example, the find in PPP_Find interface receives updates on a per-instance
+ * basis. This "per-instance" tracking allows such objects to associate
+ * themselves with an instance as "the" handler for that interface name.
+ *
+ * In the case of the find example, the find object registers with its
+ * associated instance in its constructor and unregisters in its destructor.
+ * Then whenever it gets updates with a PP_Instance parameter, it can
+ * map back to the find object corresponding to that given PP_Instance by
+ * calling GetPerInstanceObject.
+ *
+ * This lookup is done on a per-interface-name basis. This means you can
+ * only have one object of a given interface name associated with an
+ * instance.
+ *
+ * If you are adding a handler for an additional interface, be sure to
+ * register with the module (AddPluginInterface) for your interface name to
+ * get the C calls in the first place.
+ *
+ * @see RemovePerInstanceObject
+ * @see GetPerInstanceObject
+ */
+ void AddPerInstanceObject(const std::string& interface_name, void* object);
+
+ /**
+ * {PENDING: summarize Remove method here}
+ *
+ * @see AddPerInstanceObject
+ */
+ void RemovePerInstanceObject(const std::string& interface_name, void* object);
+
+ /**
+ * Look up an object previously associated with an instance. Returns NULL
+ * if the instance is invalid or there is no object for the given interface
+ * name on the instance.
+ *
+ * @see AddPerInstanceObject
+ */
+ static void* GetPerInstanceObject(PP_Instance instance,
+ const std::string& interface_name);
+
+ private:
+ PP_Instance pp_instance_;
+
+ typedef std::map<std::string, void*> InterfaceNameToObjectMap;
+ InterfaceNameToObjectMap interface_name_to_objects_;
+};
+
+} // namespace pp
+
+/**
+ * @}
+ * End addtogroup CPP
+ */
+#endif // PPAPI_CPP_INSTANCE_H_
diff --git a/ppapi/cpp/logging.h b/ppapi/cpp/logging.h
new file mode 100644
index 0000000..42061c7
--- /dev/null
+++ b/ppapi/cpp/logging.h
@@ -0,0 +1,14 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_LOGGING_H_
+#define PPAPI_CPP_LOGGING_H_
+
+#include <cassert>
+
+#define PP_DCHECK(a) assert(a)
+
+#define PP_NOTREACHED() assert(false)
+
+#endif // PPAPI_CPP_LOGGING_H_
diff --git a/ppapi/cpp/module.cc b/ppapi/cpp/module.cc
new file mode 100644
index 0000000..fe32569
--- /dev/null
+++ b/ppapi/cpp/module.cc
@@ -0,0 +1,198 @@
+// Copyright (c) 2010 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.
+
+// Note that the single accessor, Module::Get(), is not actually implemented
+// in this file. This is an intentional hook that allows users of ppapi's
+// C++ wrapper objects to provide difference semantics for how the singleton
+// object is accessed.
+//
+// In general, users of ppapi will also link in ppp_entrypoints.cc, which
+// provides a simple default implementation of Module::Get().
+//
+// A notable exception where the default ppp_entrypoints will not work is
+// when implementing "internal plugins" that are statically linked into the
+// browser. In this case, the process may actually have multiple Modules
+// loaded at once making a traditional "singleton" unworkable. To get around
+// this, the users of ppapi need to get creative about how to properly
+// implement the Module::Get() so that ppapi's C++ wrappers can find the
+// right Module object. One example solution is to use thread local storage
+// to change the Module* returned based on which thread is invoking the
+// function. Leaving Module::Get() unimplemented provides a hook for
+// implementing such behavior.
+
+#include "ppapi/cpp/module.h"
+
+#include <string.h>
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_var.h"
+#include "ppapi/c/ppp_instance.h"
+#include "ppapi/cpp/dev/url_loader_dev.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/var.h"
+
+namespace pp {
+
+// PPP_Instance implementation -------------------------------------------------
+
+bool Instance_DidCreate(PP_Instance pp_instance,
+ uint32_t argc,
+ const char* argn[],
+ const char* argv[]) {
+ Module* module_singleton = Module::Get();
+ if (!module_singleton)
+ return false;
+
+ Instance* instance = module_singleton->CreateInstance(pp_instance);
+ if (!instance)
+ return false;
+ module_singleton->current_instances_[pp_instance] = instance;
+ return instance->Init(argc, argn, argv);
+}
+
+void Instance_DidDestroy(PP_Instance instance) {
+ Module* module_singleton = Module::Get();
+ if (!module_singleton)
+ return;
+ Module::InstanceMap::iterator found =
+ module_singleton->current_instances_.find(instance);
+ if (found == module_singleton->current_instances_.end())
+ return;
+
+ // Remove it from the map before deleting to try to catch reentrancy.
+ Instance* obj = found->second;
+ module_singleton->current_instances_.erase(found);
+ delete obj;
+}
+
+void Instance_DidChangeView(PP_Instance pp_instance,
+ const PP_Rect* position,
+ const PP_Rect* clip) {
+ Module* module_singleton = Module::Get();
+ if (!module_singleton)
+ return;
+ Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return;
+ instance->DidChangeView(*position, *clip);
+}
+
+void Instance_DidChangeFocus(PP_Instance pp_instance, bool has_focus) {
+ Module* module_singleton = Module::Get();
+ if (!module_singleton)
+ return;
+ Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return;
+ instance->DidChangeFocus(has_focus);
+}
+
+bool Instance_HandleInputEvent(PP_Instance pp_instance,
+ const PP_InputEvent* event) {
+ Module* module_singleton = Module::Get();
+ if (!module_singleton)
+ return false;
+ Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return false;
+ return instance->HandleInputEvent(*event);
+}
+
+bool Instance_HandleDocumentLoad(PP_Instance pp_instance,
+ PP_Resource pp_url_loader) {
+ Module* module_singleton = Module::Get();
+ if (!module_singleton)
+ return false;
+ Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return false;
+ return instance->HandleDocumentLoad(URLLoader_Dev(pp_url_loader));
+}
+
+PP_Var Instance_GetInstanceObject(PP_Instance pp_instance) {
+ Module* module_singleton = Module::Get();
+ if (!module_singleton)
+ return Var().Detach();
+ Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return Var().Detach();
+ return instance->GetInstanceObject().Detach();
+}
+
+static PPP_Instance instance_interface = {
+ &Instance_DidCreate,
+ &Instance_DidDestroy,
+ &Instance_DidChangeView,
+ &Instance_DidChangeFocus,
+ &Instance_HandleInputEvent,
+ &Instance_HandleDocumentLoad,
+ &Instance_GetInstanceObject
+};
+
+// Module ----------------------------------------------------------------------
+
+Module::Module() : pp_module_(0), get_browser_interface_(NULL), core_(NULL) {
+}
+
+Module::~Module() {
+ delete core_;
+ core_ = NULL;
+}
+
+const void* Module::GetPluginInterface(const char* interface_name) {
+ if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0)
+ return &instance_interface;
+
+ // Now see if anything was dynamically registered.
+ InterfaceMap::const_iterator found = additional_interfaces_.find(
+ std::string(interface_name));
+ if (found != additional_interfaces_.end())
+ return found->second;
+
+ return NULL;
+}
+
+const void* Module::GetBrowserInterface(const char* interface_name) {
+ return get_browser_interface_(interface_name);
+}
+
+Instance* Module::InstanceForPPInstance(PP_Instance instance) {
+ InstanceMap::iterator found = current_instances_.find(instance);
+ if (found == current_instances_.end())
+ return NULL;
+ return found->second;
+}
+
+void Module::AddPluginInterface(const std::string& interface_name,
+ const void* vtable) {
+ // Verify that we're not trying to register an interface that's already
+ // handled, and if it is, that we're re-registering with the same vtable.
+ // Calling GetPluginInterface rather than looking it up in the map allows
+ // us to also catch "internal" ones in addition to just previously added ones.
+ const void* existing_interface = GetPluginInterface(interface_name.c_str());
+ if (existing_interface) {
+ PP_DCHECK(vtable == existing_interface);
+ return;
+ }
+ additional_interfaces_[interface_name] = vtable;
+}
+
+bool Module::InternalInit(PP_Module mod,
+ PPB_GetInterface get_browser_interface) {
+ pp_module_ = mod;
+ get_browser_interface_ = get_browser_interface;
+
+ // Get the core interface which we require to run.
+ const PPB_Core* core = reinterpret_cast<const PPB_Core*>(GetBrowserInterface(
+ PPB_CORE_INTERFACE));
+ if (!core)
+ return false;
+ core_ = new Core(core);
+
+ return Init();
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/module.h b/ppapi/cpp/module.h
new file mode 100644
index 0000000..362eedf
--- /dev/null
+++ b/ppapi/cpp/module.h
@@ -0,0 +1,123 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_MODULE_H_
+#define PPAPI_CPP_MODULE_H_
+
+#include <map>
+#include <string>
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_module.h"
+#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/ppb.h"
+#include "ppapi/c/ppb_core.h"
+#include "ppapi/cpp/core.h"
+
+namespace pp {
+
+class Instance;
+
+class Module {
+ public:
+ // You may not call any other PP functions from the constructor, put them
+ // in Init instead. Various things will not be set up until the constructor
+ // completes.
+ Module();
+ virtual ~Module();
+
+ // Returns the global instance of this module object, or NULL if the module
+ // is not initialized yet.
+ static Module* Get();
+
+ // This function will be automatically called after the object is created.
+ // This is where you can put functions that rely on other parts of the API,
+ // now that the module has been created.
+ virtual bool Init() { return true; }
+
+ // Returns the internal module handle.
+ PP_Module pp_module() const { return pp_module_; }
+
+ // Returns the internal get_browser_interface pointer.
+ // TODO(sehr): This should be removed once the NaCl browser plugin no longer
+ // needs it.
+ PPB_GetInterface get_browser_interface() const {
+ return get_browser_interface_;
+ }
+
+ // Returns the core interface for doing basic global operations. This is
+ // guaranteed to be non-NULL once the module has successfully initialized
+ // and during the Init() call.
+ //
+ // It will be NULL before Init() has been called.
+ Core* core() { return core_; }
+
+ // Implements GetInterface for the browser to get plugin interfaces. If you
+ // need to provide your own implementations of new interfaces, you can use
+ // AddPluginInterface which this function will use.
+ const void* GetPluginInterface(const char* interface_name);
+
+ // Returns an interface in the browser.
+ const void* GetBrowserInterface(const char* interface_name);
+
+ // Returns the object associated with this PP_Instance, or NULL if one is
+ // not found.
+ Instance* InstanceForPPInstance(PP_Instance instance);
+
+ // Adds a handler for a given interface name. When the browser requests
+ // that interface name, the given |vtable| will be returned.
+ //
+ // In general, plugins will not need to call this directly. Instead, the
+ // C++ wrappers for each interface will register themselves with this
+ // function.
+ //
+ // This function may be called more than once with the same interface name
+ // and vtable with no effect. However, it may not be used to register a
+ // different vtable for an already-registered interface. It will assert for
+ // a different registration for an already-registered interface in debug
+ // mode, and just ignore the registration in release mode.
+ void AddPluginInterface(const std::string& interface_name,
+ const void* vtable);
+
+ // Sets the browser interface and calls the regular init function that
+ // can be overridden by the base classes.
+ //
+ // TODO(brettw) make this private when I can figure out how to make the
+ // initialize function a friend.
+ bool InternalInit(PP_Module mod,
+ PPB_GetInterface get_browser_interface);
+
+ protected:
+ // Override to create your own plugin type.
+ virtual Instance* CreateInstance(PP_Instance instance) = 0;
+
+ private:
+ friend bool Instance_DidCreate(PP_Instance pp_instance,
+ uint32_t argc,
+ const char* argn[],
+ const char* argv[]);
+ friend void Instance_DidDestroy(PP_Instance instance);
+
+ // Unimplemented (disallow copy and assign).
+ Module(const Module&);
+ Module& operator=(const Module&);
+
+ // Instance tracking.
+ typedef std::map<PP_Instance, Instance*> InstanceMap;
+ InstanceMap current_instances_;
+
+ PP_Module pp_module_;
+ PPB_GetInterface get_browser_interface_;
+
+ Core* core_;
+
+ // All additional interfaces this plugin can handle as registered by
+ // AddPluginInterface.
+ typedef std::map<std::string, const void*> InterfaceMap;
+ InterfaceMap additional_interfaces_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_MODULE_H_
diff --git a/ppapi/cpp/module_embedder.h b/ppapi/cpp/module_embedder.h
new file mode 100644
index 0000000..c384364
--- /dev/null
+++ b/ppapi/cpp/module_embedder.h
@@ -0,0 +1,20 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_MODULE_EMBEDDER_H_
+#define PPAPI_CPP_MODULE_EMBEDDER_H_
+
+namespace pp {
+
+class Module;
+// Implemented by the embedder.
+//
+// Creates the pp::Module object associated with this plugin. Returns the
+// module if it was successfully created, or NULL on failure. Upon failure,
+// the plugin will be unloaded.
+pp::Module* CreateModule();
+
+} // namespace pp
+
+#endif // PPAPI_CPP_MODULE_EMBEDDER_H_
diff --git a/ppapi/cpp/module_impl.h b/ppapi/cpp/module_impl.h
new file mode 100644
index 0000000..9cde170
--- /dev/null
+++ b/ppapi/cpp/module_impl.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_MODULE_IMPL_H_
+#define PPAPI_CPP_MODULE_IMPL_H_
+
+#include "ppapi/cpp/module.h"
+
+namespace {
+
+template <typename T> class DeviceFuncs {
+ public:
+ explicit DeviceFuncs(const char* ifname) : ifname_(ifname), funcs_(NULL) {}
+
+ operator T const*() {
+ if (!funcs_) {
+ funcs_ = reinterpret_cast<T const*>(
+ pp::Module::Get()->GetBrowserInterface(ifname_));
+ }
+ return funcs_;
+ }
+
+ // This version doesn't check for existence of the function object. It is
+ // used so that, for DeviceFuncs f, the expression:
+ // if (f) f->doSomething();
+ // checks the existence only once.
+ T const* operator->() const { return funcs_; }
+
+ private:
+ DeviceFuncs(const DeviceFuncs&other);
+ DeviceFuncs &operator=(const DeviceFuncs &other);
+
+ const char* ifname_;
+ T const* funcs_;
+};
+
+} // namespace
+
+#endif // PPAPI_CPP_MODULE_IMPL_H_
+
diff --git a/ppapi/cpp/non_thread_safe_ref_count.h b/ppapi/cpp/non_thread_safe_ref_count.h
new file mode 100644
index 0000000..d827209
--- /dev/null
+++ b/ppapi/cpp/non_thread_safe_ref_count.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_NON_THREAD_SAFE_REF_COUNT_H_
+#define PPAPI_CPP_NON_THREAD_SAFE_REF_COUNT_H_
+
+#include "ppapi/cpp/core.h"
+#include "ppapi/cpp/logging.h"
+#include "ppapi/cpp/module.h"
+
+namespace pp {
+
+// Simple ref-count that isn't thread safe. Note: in Debug mode, it checks that
+// it is either called on the main thread, or always called on another thread.
+class NonThreadSafeRefCount {
+ public:
+ NonThreadSafeRefCount()
+ : ref_(0) {
+#ifndef NDEBUG
+ is_main_thread_ = Module::Get()->core()->IsMainThread();
+#endif
+ }
+
+ ~NonThreadSafeRefCount() {
+ PP_DCHECK(is_main_thread_ == Module::Get()->core()->IsMainThread());
+ }
+
+ int32_t AddRef() {
+ PP_DCHECK(is_main_thread_ == Module::Get()->core()->IsMainThread());
+ return ++ref_;
+ }
+
+ int32_t Release() {
+ PP_DCHECK(is_main_thread_ == Module::Get()->core()->IsMainThread());
+ return --ref_;
+ }
+
+ private:
+ int32_t ref_;
+#ifndef NDEBUG
+ bool is_main_thread_;
+#endif
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_NON_THREAD_SAFE_REF_COUNT_H_
diff --git a/ppapi/cpp/paint_aggregator.cc b/ppapi/cpp/paint_aggregator.cc
new file mode 100644
index 0000000..7f54331
--- /dev/null
+++ b/ppapi/cpp/paint_aggregator.cc
@@ -0,0 +1,274 @@
+// Copyright (c) 2010 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/paint_aggregator.h"
+
+#include <algorithm>
+
+#include "ppapi/cpp/logging.h"
+
+// ----------------------------------------------------------------------------
+// ALGORITHM NOTES
+//
+// We attempt to maintain a scroll rect in the presence of invalidations that
+// are contained within the scroll rect. If an invalidation crosses a scroll
+// rect, then we just treat the scroll rect as an invalidation rect.
+//
+// For invalidations performed prior to scrolling and contained within the
+// scroll rect, we offset the invalidation rects to account for the fact that
+// the consumer will perform scrolling before painting.
+//
+// We only support scrolling along one axis at a time. A diagonal scroll will
+// therefore be treated as an invalidation.
+// ----------------------------------------------------------------------------
+
+namespace pp {
+
+PaintAggregator::InternalPaintUpdate::InternalPaintUpdate() {
+}
+
+Rect PaintAggregator::InternalPaintUpdate::GetScrollDamage() const {
+ // Should only be scrolling in one direction at a time.
+ PP_DCHECK(!(scroll_delta.x() && scroll_delta.y()));
+
+ Rect damaged_rect;
+
+ // Compute the region we will expose by scrolling, and paint that into a
+ // shared memory section.
+ if (scroll_delta.x()) {
+ int32_t dx = scroll_delta.x();
+ damaged_rect.set_y(scroll_rect.y());
+ damaged_rect.set_height(scroll_rect.height());
+ if (dx > 0) {
+ damaged_rect.set_x(scroll_rect.x());
+ damaged_rect.set_width(dx);
+ } else {
+ damaged_rect.set_x(scroll_rect.right() + dx);
+ damaged_rect.set_width(-dx);
+ }
+ } else {
+ int32_t dy = scroll_delta.y();
+ damaged_rect.set_x(scroll_rect.x());
+ damaged_rect.set_width(scroll_rect.width());
+ if (dy > 0) {
+ damaged_rect.set_y(scroll_rect.y());
+ damaged_rect.set_height(dy);
+ } else {
+ damaged_rect.set_y(scroll_rect.bottom() + dy);
+ damaged_rect.set_height(-dy);
+ }
+ }
+
+ // In case the scroll offset exceeds the width/height of the scroll rect
+ return scroll_rect.Intersect(damaged_rect);
+}
+
+Rect PaintAggregator::InternalPaintUpdate::GetPaintBounds() const {
+ Rect bounds;
+ for (size_t i = 0; i < paint_rects.size(); ++i)
+ bounds = bounds.Union(paint_rects[i]);
+ return bounds;
+}
+
+PaintAggregator::PaintAggregator()
+ : max_redundant_paint_to_scroll_area_(0.8f),
+ max_paint_rects_(10) {
+}
+
+bool PaintAggregator::HasPendingUpdate() const {
+ return !update_.scroll_rect.IsEmpty() || !update_.paint_rects.empty();
+}
+
+void PaintAggregator::ClearPendingUpdate() {
+ update_ = InternalPaintUpdate();
+}
+
+PaintAggregator::PaintUpdate PaintAggregator::GetPendingUpdate() const {
+ // Convert the internal paint update to the external one, which includes a
+ // bit more precomputed info for the caller.
+ PaintUpdate ret;
+ ret.scroll_delta = update_.scroll_delta;
+ ret.scroll_rect = update_.scroll_rect;
+ ret.has_scroll = ret.scroll_delta.x() != 0 || ret.scroll_delta.y() != 0;
+
+ ret.paint_rects.reserve(update_.paint_rects.size() + 1);
+ for (size_t i = 0; i < update_.paint_rects.size(); i++)
+ ret.paint_rects.push_back(update_.paint_rects[i]);
+
+ ret.paint_bounds = update_.GetPaintBounds();
+
+ // Also include the scroll damage (if any) in the paint rects.
+ if (ret.has_scroll) {
+ PP_Rect scroll_damage = update_.GetScrollDamage();
+ ret.paint_rects.push_back(scroll_damage);
+ ret.paint_bounds = ret.paint_bounds.Union(scroll_damage);
+ }
+
+ return ret;
+}
+
+void PaintAggregator::InvalidateRect(const Rect& rect) {
+ // Combine overlapping paints using smallest bounding box.
+ for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
+ const Rect& existing_rect = update_.paint_rects[i];
+ if (existing_rect.Contains(rect)) // Optimize out redundancy.
+ return;
+ if (rect.Intersects(existing_rect) || rect.SharesEdgeWith(existing_rect)) {
+ // Re-invalidate in case the union intersects other paint rects.
+ Rect combined_rect = existing_rect.Union(rect);
+ update_.paint_rects.erase(update_.paint_rects.begin() + i);
+ InvalidateRect(combined_rect);
+ return;
+ }
+ }
+
+ // Add a non-overlapping paint.
+ update_.paint_rects.push_back(rect);
+
+ // If the new paint overlaps with a scroll, then it forces an invalidation of
+ // the scroll. If the new paint is contained by a scroll, then trim off the
+ // scroll damage to avoid redundant painting.
+ if (!update_.scroll_rect.IsEmpty()) {
+ if (ShouldInvalidateScrollRect(rect)) {
+ InvalidateScrollRect();
+ } else if (update_.scroll_rect.Contains(rect)) {
+ update_.paint_rects[update_.paint_rects.size() - 1] =
+ rect.Subtract(update_.GetScrollDamage());
+ if (update_.paint_rects[update_.paint_rects.size() - 1].IsEmpty())
+ update_.paint_rects.erase(update_.paint_rects.end() - 1);
+ }
+ }
+
+ if (update_.paint_rects.size() > max_paint_rects_)
+ CombinePaintRects();
+}
+
+void PaintAggregator::ScrollRect(const Rect& clip_rect, const Point& amount) {
+ // We only support scrolling along one axis at a time.
+ if (amount.x() != 0 && amount.y() != 0) {
+ InvalidateRect(clip_rect);
+ return;
+ }
+
+ // We can only scroll one rect at a time.
+ if (!update_.scroll_rect.IsEmpty() && update_.scroll_rect != clip_rect) {
+ InvalidateRect(clip_rect);
+ return;
+ }
+
+ // Again, we only support scrolling along one axis at a time. Make sure this
+ // update doesn't scroll on a different axis than any existing one.
+ if ((amount.x() && update_.scroll_delta.y()) ||
+ (amount.y() && update_.scroll_delta.x())) {
+ InvalidateRect(clip_rect);
+ return;
+ }
+
+ // The scroll rect is new or isn't changing (though the scroll amount may
+ // be changing).
+ update_.scroll_rect = clip_rect;
+ update_.scroll_delta += amount;
+
+ // We might have just wiped out a pre-existing scroll.
+ if (update_.scroll_delta == Point()) {
+ update_.scroll_rect = Rect();
+ return;
+ }
+
+ // Adjust any contained paint rects and check for any overlapping paints.
+ for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
+ if (update_.scroll_rect.Contains(update_.paint_rects[i])) {
+ update_.paint_rects[i] = ScrollPaintRect(update_.paint_rects[i], amount);
+ // The rect may have been scrolled out of view.
+ if (update_.paint_rects[i].IsEmpty()) {
+ update_.paint_rects.erase(update_.paint_rects.begin() + i);
+ i--;
+ }
+ } else if (update_.scroll_rect.Intersects(update_.paint_rects[i])) {
+ InvalidateScrollRect();
+ return;
+ }
+ }
+
+ // If the new scroll overlaps too much with contained paint rects, then force
+ // an invalidation of the scroll.
+ if (ShouldInvalidateScrollRect(Rect()))
+ InvalidateScrollRect();
+}
+
+Rect PaintAggregator::ScrollPaintRect(const Rect& paint_rect,
+ const Point& amount) const {
+ Rect result = paint_rect;
+
+ result.Offset(amount);
+ result = update_.scroll_rect.Intersect(result);
+
+ // Subtract out the scroll damage rect to avoid redundant painting.
+ return result.Subtract(update_.GetScrollDamage());
+}
+
+bool PaintAggregator::ShouldInvalidateScrollRect(const Rect& rect) const {
+ if (!rect.IsEmpty()) {
+ if (!update_.scroll_rect.Intersects(rect))
+ return false;
+
+ if (!update_.scroll_rect.Contains(rect))
+ return true;
+ }
+
+ // Check if the combined area of all contained paint rects plus this new
+ // rect comes too close to the area of the scroll_rect. If so, then we
+ // might as well invalidate the scroll rect.
+
+ int paint_area = rect.size().GetArea();
+ for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
+ const Rect& existing_rect = update_.paint_rects[i];
+ if (update_.scroll_rect.Contains(existing_rect))
+ paint_area += existing_rect.size().GetArea();
+ }
+ int scroll_area = update_.scroll_rect.size().GetArea();
+ if (float(paint_area) / float(scroll_area) > max_redundant_paint_to_scroll_area_)
+ return true;
+
+ return false;
+}
+
+void PaintAggregator::InvalidateScrollRect() {
+ Rect scroll_rect = update_.scroll_rect;
+ update_.scroll_rect = Rect();
+ update_.scroll_delta = Point();
+ InvalidateRect(scroll_rect);
+}
+
+void PaintAggregator::CombinePaintRects() {
+ // Combine paint rects down to at most two rects: one inside the scroll_rect
+ // and one outside the scroll_rect. If there is no scroll_rect, then just
+ // use the smallest bounding box for all paint rects.
+ //
+ // NOTE: This is a fairly simple algorithm. We could get fancier by only
+ // combining two rects to get us under the max_paint_rects limit, but if we
+ // reach this method then it means we're hitting a rare case, so there's no
+ // need to over-optimize it.
+ //
+ if (update_.scroll_rect.IsEmpty()) {
+ Rect bounds = update_.GetPaintBounds();
+ update_.paint_rects.clear();
+ update_.paint_rects.push_back(bounds);
+ } else {
+ Rect inner, outer;
+ for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
+ const Rect& existing_rect = update_.paint_rects[i];
+ if (update_.scroll_rect.Contains(existing_rect)) {
+ inner = inner.Union(existing_rect);
+ } else {
+ outer = outer.Union(existing_rect);
+ }
+ }
+ update_.paint_rects.clear();
+ update_.paint_rects.push_back(inner);
+ update_.paint_rects.push_back(outer);
+ }
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/paint_aggregator.h b/ppapi/cpp/paint_aggregator.h
new file mode 100644
index 0000000..a73a998
--- /dev/null
+++ b/ppapi/cpp/paint_aggregator.h
@@ -0,0 +1,130 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_PAINT_AGGREGATOR_H_
+#define PPAPI_CPP_PAINT_AGGREGATOR_H_
+
+#include <vector>
+
+#include "ppapi/cpp/point.h"
+#include "ppapi/cpp/rect.h"
+
+namespace pp {
+
+// This class is responsible for aggregating multiple invalidation and scroll
+// commands to produce a scroll and repaint sequence. You can use this manually
+// to track your updates, but most applications will use the PaintManager to
+// additionally handle the necessary callbacks on top of the PaintAggregator
+// functionality.
+//
+// See http://code.google.com/p/ppapi/wiki/2DPaintingModel
+class PaintAggregator {
+ public:
+ struct PaintUpdate {
+ // True if there is a scroll applied. This indicates that the scroll delta
+ // and scroll_rect are nonzero (just as a convenience).
+ bool has_scroll;
+
+ // The amount to scroll by. Either the X or Y may be nonzero to indicate a
+ // scroll in that direction, but there will never be a scroll in both
+ // directions at the same time (this will be converted to a paint of the
+ // region instead).
+ //
+ // If there is no scroll, this will be (0, 0).
+ Point scroll_delta;
+
+ // The rectangle that should be scrolled by the scroll_delta. If there is no
+ // scroll, this will be (0, 0, 0, 0). We only track one scroll command at
+ // once. If there are multiple ones, they will be converted to invalidates.
+ Rect scroll_rect;
+
+ // A list of all the individual dirty rectangles. This is an aggregated list
+ // of all invalidate calls. Different rectangles may be unified to produce a
+ // minimal list with no overlap that is more efficient to paint. This list
+ // also contains the region exposed by any scroll command.
+ std::vector<Rect> paint_rects;
+
+ // The union of all paint_rects.
+ Rect paint_bounds;
+ };
+
+ PaintAggregator();
+
+ // Setters for the configuration settings. See the corresponding variables
+ // below for what these mean.
+ void set_max_redundant_paint_to_scroll_area(float area) {
+ max_redundant_paint_to_scroll_area_ = area;
+ }
+ void set_max_paint_rects(size_t max_rects) {
+ max_paint_rects_ = max_rects;
+ }
+
+ // There is a PendingUpdate if InvalidateRect or ScrollRect were called and
+ // ClearPendingUpdate was not called.
+ bool HasPendingUpdate() const;
+ void ClearPendingUpdate();
+
+ PaintUpdate GetPendingUpdate() const;
+
+ // The given rect should be repainted.
+ void InvalidateRect(const Rect& rect);
+
+ // The given rect should be scrolled by the given amounts.
+ void ScrollRect(const Rect& clip_rect, const Point& amount);
+
+ private:
+ // This structure is an internal version of PaintUpdate. It's different in
+ // two respects:
+ //
+ // - The scroll damange (area exposed by the scroll operation, if any) is
+ // maintained separately from the dirty rects generated by calling
+ // InvalidateRect. We need to know this distinction for some operations.
+ //
+ // - The paint bounds union is computed on the fly so we don't have to keep
+ // a rectangle up-to-date as we do different operations.
+ class InternalPaintUpdate {
+ public:
+ InternalPaintUpdate();
+
+ // Computes the rect damaged by scrolling within |scroll_rect| by
+ // |scroll_delta|. This rect must be repainted. It is not included in
+ // paint_rects or in the rect returned by GetPaintBounds.
+ Rect GetScrollDamage() const;
+
+ // Returns the smallest rect containing all paint rects, not including the
+ // scroll damage rect.
+ Rect GetPaintBounds() const;
+
+ Point scroll_delta;
+ Rect scroll_rect;
+
+ // Does not include the scroll damage rect.
+ std::vector<Rect> paint_rects;
+ };
+
+ Rect ScrollPaintRect(const Rect& paint_rect, const Point& amount) const;
+ bool ShouldInvalidateScrollRect(const Rect& rect) const;
+ void InvalidateScrollRect();
+ void CombinePaintRects();
+
+ InternalPaintUpdate update_;
+
+ // If the combined area of paint rects contained within the scroll rect grows
+ // too large, then we might as well just treat the scroll rect as a paint
+ // rect. This constant sets the max ratio of paint rect area to scroll rect
+ // area that we will tolerate before downgrading the scroll into a repaint.
+ float max_redundant_paint_to_scroll_area_;
+
+ // The maximum number of paint rects. If we exceed this limit, then we'll
+ // start combining paint rects (see CombinePaintRects). This limiting can be
+ // important since there is typically some overhead in deciding what to
+ // paint. If your plugin is fast at doing these computations, raise this
+ // threshold, if your plugin is slow, lower it (probably requires some
+ // tuning to find the right value).
+ size_t max_paint_rects_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_PAINT_AGGREGATOR_H_
diff --git a/ppapi/cpp/paint_manager.cc b/ppapi/cpp/paint_manager.cc
new file mode 100644
index 0000000..87c0750
--- /dev/null
+++ b/ppapi/cpp/paint_manager.cc
@@ -0,0 +1,174 @@
+// Copyright (c) 2010 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/paint_manager.h"
+
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/logging.h"
+#include "ppapi/cpp/module.h"
+
+namespace pp {
+
+PaintManager::PaintManager()
+ : instance_(NULL),
+ client_(NULL),
+ is_always_opaque_(false),
+ callback_factory_(NULL) {
+ // Set the callback object outside of the initializer list to avoid a
+ // compiler warning about using "this" in an initializer list.
+ callback_factory_.Initialize(this);
+}
+
+PaintManager::PaintManager(Instance* instance,
+ Client* client,
+ bool is_always_opaque)
+ : instance_(instance),
+ client_(client),
+ is_always_opaque_(is_always_opaque),
+ callback_factory_(NULL) {
+ // Set the callback object outside of the initializer list to avoid a
+ // compiler warning about using "this" in an initializer list.
+ callback_factory_.Initialize(this);
+
+ // You can not use a NULL client pointer.
+ PP_DCHECK(client);
+}
+
+PaintManager::~PaintManager() {
+}
+
+void PaintManager::Initialize(Instance* instance,
+ Client* client,
+ bool is_always_opaque) {
+ PP_DCHECK(!instance_ && !client_); // Can't initialize twice.
+ instance_ = instance;
+ client_ = client;
+ is_always_opaque_ = is_always_opaque;
+}
+
+void PaintManager::SetSize(const Size& new_size) {
+ if (new_size == graphics_.size())
+ return;
+
+ graphics_ = Graphics2D(new_size, is_always_opaque_);
+ if (graphics_.is_null())
+ return;
+ instance_->BindGraphics(graphics_);
+
+ manual_callback_pending_ = false;
+ flush_pending_ = false;
+ callback_factory_.CancelAll();
+
+ Invalidate();
+}
+
+void PaintManager::Invalidate() {
+ // You must call SetDevice before using.
+ PP_DCHECK(!graphics_.is_null());
+
+ EnsureCallbackPending();
+ aggregator_.InvalidateRect(Rect(graphics_.size()));
+}
+
+void PaintManager::InvalidateRect(const Rect& rect) {
+ // You must call SetDevice before using.
+ PP_DCHECK(!graphics_.is_null());
+
+ // Clip the rect to the device area.
+ Rect clipped_rect = rect.Intersect(Rect(graphics_.size()));
+ if (clipped_rect.IsEmpty())
+ return; // Nothing to do.
+
+ EnsureCallbackPending();
+ aggregator_.InvalidateRect(clipped_rect);
+}
+
+void PaintManager::ScrollRect(const Rect& clip_rect, const Point& amount) {
+ // You must call SetDevice before using.
+ PP_DCHECK(!graphics_.is_null());
+
+ EnsureCallbackPending();
+ aggregator_.ScrollRect(clip_rect, amount);
+}
+
+void PaintManager::EnsureCallbackPending() {
+ // The best way for us to do the next update is to get a notification that
+ // a previous one has completed. So if we're already waiting for one, we
+ // don't have to do anything differently now.
+ if (flush_pending_)
+ return;
+
+ // If no flush is pending, we need to do a manual call to get back to the
+ // main thread. We may have one already pending, or we may need to schedule.
+ if (manual_callback_pending_)
+ return;
+
+ Module::Get()->core()->CallOnMainThread(
+ 0,
+ callback_factory_.NewCallback(&PaintManager::OnManualCallbackComplete),
+ 0);
+ manual_callback_pending_ = true;
+}
+
+void PaintManager::DoPaint() {
+ PP_DCHECK(aggregator_.HasPendingUpdate());
+
+ // Make a copy of the pending update and clear the pending update flag before
+ // actually painting. A plugin might cause invalidates in its Paint code, and
+ // we want those to go to the *next* paint.
+ PaintAggregator::PaintUpdate update = aggregator_.GetPendingUpdate();
+ aggregator_.ClearPendingUpdate();
+
+ // Apply any scroll before asking the client to paint.
+ if (update.has_scroll)
+ graphics_.Scroll(update.scroll_rect, update.scroll_delta);
+
+ if (!client_->OnPaint(graphics_, update.paint_rects, update.paint_bounds))
+ return; // Nothing was painted, don't schedule a flush.
+
+ int32_t result = graphics_.Flush(
+ callback_factory_.NewCallback(&PaintManager::OnFlushComplete));
+
+ // If you trigger this assertion, then your plugin has called Flush()
+ // manually. When using the PaintManager, you should not call Flush, it will
+ // handle that for you because it needs to know when it can do the next paint
+ // by implementing the flush callback.
+ //
+ // Another possible cause of this assertion is re-using devices. If you
+ // use one device, swap it with another, then swap it back, we won't know
+ // that we've already scheduled a Flush on the first device. It's best to not
+ // re-use devices in this way.
+ PP_DCHECK(result != PP_ERROR_INPROGRESS);
+
+ if (result == PP_ERROR_WOULDBLOCK) {
+ flush_pending_ = true;
+ } else {
+ PP_DCHECK(result == PP_OK); // Catch all other errors in debug mode.
+ }
+}
+
+void PaintManager::OnFlushComplete(int32_t) {
+ PP_DCHECK(flush_pending_);
+ flush_pending_ = false;
+
+ // If more paints were enqueued while we were waiting for the flush to
+ // complete, execute them now.
+ if (aggregator_.HasPendingUpdate())
+ DoPaint();
+}
+
+void PaintManager::OnManualCallbackComplete(int32_t) {
+ PP_DCHECK(manual_callback_pending_);
+ manual_callback_pending_ = false;
+
+ // Just because we have a manual callback doesn't mean there are actually any
+ // invalid regions. Even though we only schedule this callback when something
+ // is pending, a Flush callback could have come in before this callback was
+ // executed and that could have cleared the queue.
+ if (aggregator_.HasPendingUpdate())
+ DoPaint();
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/paint_manager.h b/ppapi/cpp/paint_manager.h
new file mode 100644
index 0000000..d8cba66
--- /dev/null
+++ b/ppapi/cpp/paint_manager.h
@@ -0,0 +1,207 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_PAINT_MANAGER_H_
+#define PPAPI_CPP_PAINT_MANAGER_H_
+
+#include <vector>
+
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/paint_aggregator.h"
+
+namespace pp {
+
+class Graphics2D;
+class Instance;
+class Point;
+class Rect;
+
+// This class converts the "plugin push" model of painting in PPAPI to a paint
+// request at a later time. Usage is that you call Invalidate and Scroll, and
+// implement the Client interface. Your OnPaint handler will then get called
+// with coalesced paint events.
+//
+// This class is basically a PaintAggregator that groups updates, plus
+// management of callbacks for scheduling paints.
+//
+// Typical usage:
+//
+// class MyClass : public pp::Instance, public PaintManager::Client {
+// public:
+// MyClass() {
+// paint_manager_.Initialize(this, this, false);
+// }
+//
+// void ViewChanged(const pp::Rect& position, const pp::Rect& clip) {
+// paint_manager_.SetSize(position.size());
+// }
+//
+// void DoSomething() {
+// // This function does something like respond to an event that causes
+// // the screen to need updating.
+// paint_manager_.InvalidateRect(some_rect);
+// }
+//
+// // Implementation of PaintManager::Client
+// virtual bool OnPaint(pp::Graphics2D& device,
+// const pp::PaintUpdate& update) {
+// // If our app needed scrolling, we would apply that first here.
+//
+// // Then we would either repaint the area returned by GetPaintBounds or
+// // iterate through all the paint_rects.
+//
+// // The caller will call Flush() for us, so don't do that here.
+// return true;
+// }
+//
+// private:
+// pp::PaintManager paint_manager_;
+// };
+class PaintManager {
+ public:
+ class Client {
+ public:
+ // Paints the given invalid area of the plugin to the given graphics
+ // device. Returns true if anything was painted.
+ //
+ // You are given the list of rects to paint in |paint_rects|, and the
+ // union of all of these rects in |paint_bounds|. You only have to paint
+ // the area inside each of the |paint_rects|, but can paint more if you
+ // want (some apps may just want to paint the union).
+ //
+ // Do not call Flush() on the graphics device, this will be done
+ // automatically if you return true from this function since the
+ // PaintManager needs to handle the callback.
+ //
+ // It is legal for you to cause invalidates inside of Paint which will
+ // then get executed as soon as the Flush for this update has completed.
+ // However, this is not very nice to the host system since it will spin the
+ // CPU, possibly updating much faster than necessary. It is best to have a
+ // 1/60 second timer to do an invalidate instead. This will limit your
+ // animation to the slower of 60Hz or "however fast Flush can complete."
+ virtual bool OnPaint(Graphics2D& graphics,
+ const std::vector<Rect>& paint_rects,
+ const Rect& paint_bounds) = 0;
+
+ protected:
+ // You shouldn't be doing deleting through this interface.
+ virtual ~Client() {}
+ };
+
+ // If you use this version of the constructor, you must call Initialize()
+ // below.
+ PaintManager();
+
+ // The instance is the plugin instance using this paint manager to do its
+ // painting. Painting will automatically go to this instance and you don't
+ // have to manually bind any device context (this is all handled by the
+ // paint manager).
+ //
+ // The Client is a non-owning pointer and must remain valid (normally the
+ // object implementing the Client interface will own the paint manager).
+ //
+ // The is_always_opaque flag will be passed to the device contexts that this
+ // class creates. Set this to true if your plugin always draws an opaque
+ // image to the device. This is used as a hint to the browser that it does
+ // not need to do alpha blending, which speeds up painting. If you generate
+ // non-opqaue pixels or aren't sure, set this to false for more general
+ // blending.
+ //
+ // If you set is_always_opaque, your alpha channel should always be set to
+ // 0xFF or there may be painting artifacts. Being opaque will allow the
+ // browser to do a memcpy rather than a blend to paint the plugin, and this
+ // means your alpha values will get set on the page backing store. If these
+ // values are incorrect, it could mess up future blending. If you aren't
+ // sure, it is always correct to specify that it it not opaque.
+ //
+ // You will need to call SetSize before this class will do anything. Normally
+ // you do this from the ViewChanged method of your plugin instance.
+ PaintManager(Instance* instance, Client* client, bool is_always_opaque);
+
+ ~PaintManager();
+
+ // You must call this function before using if you use the 0-arg constructor.
+ // See the constructor for what these arguments mean.
+ void Initialize(Instance* instance, Client* client, bool is_always_opaque);
+
+ // Setters for the configuration settings in the paint aggregator.
+ // See paint_aggregator.h for what these mean.
+ void set_max_redundant_paint_to_scroll_area(float area) {
+ aggregator_.set_max_redundant_paint_to_scroll_area(area);
+ }
+ void set_max_paint_rects(size_t max_rects) {
+ aggregator_.set_max_paint_rects(max_rects);
+ }
+
+ // Sets the size of the plugin. If the size is the same as the previous call,
+ // this will be a NOP. If the size has changed, a new device will be
+ // allocated to the given size and a paint to that device will be scheduled.
+ //
+ // This is intended to be called from ViewChanged with the size of the
+ // plugin. Since it tracks the old size and only allocates when the size
+ // changes, you can always call this function without worrying about whether
+ // the size changed or ViewChanged is called for another reason (like the
+ // position changed).
+ void SetSize(const Size& new_size);
+
+ // Provides access to the underlying device in case you need it. Note: if
+ // you call Flush on this device the paint manager will get very confused,
+ // don't do this!
+ const Graphics2D& graphics() const { return graphics_; }
+ Graphics2D& graphics() { return graphics_; }
+
+ // Invalidate the entire plugin.
+ void Invalidate();
+
+ // Invalidate the given rect.
+ void InvalidateRect(const Rect& rect);
+
+ // The given rect should be scrolled by the given amounts.
+ void ScrollRect(const Rect& clip_rect, const Point& amount);
+
+ private:
+ // Disallow copy and assign (these are unimplemented).
+ PaintManager(const PaintManager&);
+ PaintManager& operator=(const PaintManager&);
+
+ // Makes sure there is a callback that will trigger a paint at a later time.
+ // This will be either a Flush callback telling us we're allowed to generate
+ // more data, or, if there's no flush callback pending, a manual call back
+ // to the message loop via ExecuteOnMainThread.
+ void EnsureCallbackPending();
+
+ // Does the client paint and executes a Flush if necessary.
+ void DoPaint();
+
+ // Callback for asynchronous completion of Flush.
+ void OnFlushComplete(int32_t);
+
+ // Callback for manual scheduling of paints when there is no flush callback
+ // pending.
+ void OnManualCallbackComplete(int32_t);
+
+ Instance* instance_;
+
+ // Non-owning pointer. See the constructor.
+ Client* client_;
+
+ bool is_always_opaque_;
+
+ CompletionCallbackFactory<PaintManager> callback_factory_;
+
+ // This graphics device will be is_null() if no graphics has been manually
+ // set yet.
+ Graphics2D graphics_;
+
+ PaintAggregator aggregator_;
+
+ // See comment for EnsureCallbackPending for more on how these work.
+ bool manual_callback_pending_;
+ bool flush_pending_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_PAINT_MANAGER_H_
diff --git a/ppapi/cpp/point.h b/ppapi/cpp/point.h
new file mode 100644
index 0000000..ce1c5a4
--- /dev/null
+++ b/ppapi/cpp/point.h
@@ -0,0 +1,93 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_POINT_H_
+#define PPAPI_CPP_POINT_H_
+
+#include "ppapi/c/pp_point.h"
+
+namespace pp {
+
+// A point has an x and y coordinate.
+class Point {
+ public:
+ Point() {
+ point_.x = 0;
+ point_.y = 0;
+ }
+ Point(int32_t in_x, int32_t in_y) {
+ point_.x = in_x;
+ point_.y = in_y;
+ }
+ Point(const PP_Point& point) { // Implicit.
+ point_.x = point.x;
+ point_.y = point.y;
+ }
+
+ ~Point() {
+ }
+
+ operator PP_Point() const {
+ return point_;
+ }
+ const PP_Point& pp_point() const {
+ return point_;
+ }
+ PP_Point& pp_point() {
+ return point_;
+ }
+
+ int32_t x() const { return point_.x; }
+ void set_x(int32_t in_x) {
+ point_.x = in_x;
+ }
+
+ int32_t y() const { return point_.y; }
+ void set_y(int32_t in_y) {
+ point_.y = in_y;
+ }
+
+ Point operator+(const Point& other) const {
+ return Point(x() + other.x(), y() + other.y());
+ }
+ Point operator-(const Point& other) const {
+ return Point(x() - other.x(), y() - other.y());
+ }
+
+ Point& operator+=(const Point& other) {
+ point_.x += other.x();
+ point_.y += other.y();
+ return *this;
+ }
+ Point& operator-=(const Point& other) {
+ point_.x -= other.x();
+ point_.y -= other.y();
+ return *this;
+ }
+
+ void swap(Point& other) {
+ int32_t x = point_.x;
+ int32_t y = point_.y;
+ point_.x = other.point_.x;
+ point_.y = other.point_.y;
+ other.point_.x = x;
+ other.point_.y = y;
+ }
+
+ private:
+ PP_Point point_;
+};
+
+} // namespace pp
+
+inline bool operator==(const pp::Point& lhs, const pp::Point& rhs) {
+ return lhs.x() == rhs.x() && lhs.y() == rhs.y();
+}
+
+inline bool operator!=(const pp::Point& lhs, const pp::Point& rhs) {
+ return !(lhs == rhs);
+}
+
+#endif // PPAPI_CPP_POINT_H_
+
diff --git a/ppapi/cpp/ppp_entrypoints.cc b/ppapi/cpp/ppp_entrypoints.cc
new file mode 100644
index 0000000..c3e7568
--- /dev/null
+++ b/ppapi/cpp/ppp_entrypoints.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2010 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.
+
+// When used in conjunction with module_embedder.h, this gives a default
+// implementation of ppp.h for clients of the ppapi C++ interface. Most
+// plugin implementors can export their derivation of Module by just
+// linking to this implementation.
+
+#include "ppapi/c/ppb.h"
+#include "ppapi/c/ppp.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_embedder.h"
+
+static pp::Module* g_module_singleton = NULL;
+
+namespace pp {
+
+// Give a default implementation of Module::Get(). See module.cc for details.
+pp::Module* Module::Get() {
+ return g_module_singleton;
+}
+
+} // namespace pp
+
+// Global PPP functions --------------------------------------------------------
+
+PP_EXPORT int32_t PPP_InitializeModule(PP_Module module_id,
+ PPB_GetInterface get_browser_interface) {
+ pp::Module* module = pp::CreateModule();
+ if (!module)
+ return PP_ERROR_FAILED;
+
+ if (!module->InternalInit(module_id, get_browser_interface)) {
+ delete module;
+ return PP_ERROR_FAILED;
+ }
+ g_module_singleton = module;
+ return PP_OK;
+}
+
+PP_EXPORT void PPP_ShutdownModule() {
+ delete g_module_singleton;
+ g_module_singleton = NULL;
+}
+
+PP_EXPORT const void* PPP_GetInterface(const char* interface_name) {
+ if (!g_module_singleton)
+ return NULL;
+ return g_module_singleton->GetPluginInterface(interface_name);
+}
diff --git a/ppapi/cpp/rect.cc b/ppapi/cpp/rect.cc
new file mode 100644
index 0000000..b57be2d
--- /dev/null
+++ b/ppapi/cpp/rect.cc
@@ -0,0 +1,137 @@
+// Copyright (c) 2010 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/rect.h"
+
+#include <algorithm>
+
+namespace {
+
+void AdjustAlongAxis(int32_t dst_origin, int32_t dst_size,
+ int32_t* origin, int32_t* size) {
+ if (*origin < dst_origin) {
+ *origin = dst_origin;
+ *size = std::min(dst_size, *size);
+ } else {
+ *size = std::min(dst_size, *size);
+ *origin = std::min(dst_origin + dst_size, *origin + *size) - *size;
+ }
+}
+
+} // namespace
+
+namespace pp {
+
+void Rect::Inset(int32_t left, int32_t top, int32_t right, int32_t bottom) {
+ Offset(left, top);
+ set_width(std::max<int32_t>(width() - left - right, 0));
+ set_height(std::max<int32_t>(height() - top - bottom, 0));
+}
+
+void Rect::Offset(int32_t horizontal, int32_t vertical) {
+ rect_.point.x += horizontal;
+ rect_.point.y += vertical;
+}
+
+void Rect::swap(Rect& other) {
+ std::swap(rect_.point.x, other.rect_.point.x);
+ std::swap(rect_.point.y, other.rect_.point.y);
+ std::swap(rect_.size.width, other.rect_.size.width);
+ std::swap(rect_.size.height, other.rect_.size.height);
+}
+
+bool Rect::Contains(int32_t point_x, int32_t point_y) const {
+ return (point_x >= x()) && (point_x < right()) &&
+ (point_y >= y()) && (point_y < bottom());
+}
+
+bool Rect::Contains(const Rect& rect) const {
+ return (rect.x() >= x() && rect.right() <= right() &&
+ rect.y() >= y() && rect.bottom() <= bottom());
+}
+
+bool Rect::Intersects(const Rect& rect) const {
+ return !(rect.x() >= right() || rect.right() <= x() ||
+ rect.y() >= bottom() || rect.bottom() <= y());
+}
+
+Rect Rect::Intersect(const Rect& rect) const {
+ int32_t rx = std::max(x(), rect.x());
+ int32_t ry = std::max(y(), rect.y());
+ int32_t rr = std::min(right(), rect.right());
+ int32_t rb = std::min(bottom(), rect.bottom());
+
+ if (rx >= rr || ry >= rb)
+ rx = ry = rr = rb = 0; // non-intersecting
+
+ return Rect(rx, ry, rr - rx, rb - ry);
+}
+
+Rect Rect::Union(const Rect& rect) const {
+ // special case empty rects...
+ if (IsEmpty())
+ return rect;
+ if (rect.IsEmpty())
+ return *this;
+
+ int32_t rx = std::min(x(), rect.x());
+ int32_t ry = std::min(y(), rect.y());
+ int32_t rr = std::max(right(), rect.right());
+ int32_t rb = std::max(bottom(), rect.bottom());
+
+ return Rect(rx, ry, rr - rx, rb - ry);
+}
+
+Rect Rect::Subtract(const Rect& rect) const {
+ // boundary cases:
+ if (!Intersects(rect))
+ return *this;
+ if (rect.Contains(*this))
+ return Rect();
+
+ int32_t rx = x();
+ int32_t ry = y();
+ int32_t rr = right();
+ int32_t rb = bottom();
+
+ if (rect.y() <= y() && rect.bottom() >= bottom()) {
+ // complete int32_tersection in the y-direction
+ if (rect.x() <= x()) {
+ rx = rect.right();
+ } else {
+ rr = rect.x();
+ }
+ } else if (rect.x() <= x() && rect.right() >= right()) {
+ // complete int32_tersection in the x-direction
+ if (rect.y() <= y()) {
+ ry = rect.bottom();
+ } else {
+ rb = rect.y();
+ }
+ }
+ return Rect(rx, ry, rr - rx, rb - ry);
+}
+
+Rect Rect::AdjustToFit(const Rect& rect) const {
+ int32_t new_x = x();
+ int32_t new_y = y();
+ int32_t new_width = width();
+ int32_t new_height = height();
+ AdjustAlongAxis(rect.x(), rect.width(), &new_x, &new_width);
+ AdjustAlongAxis(rect.y(), rect.height(), &new_y, &new_height);
+ return Rect(new_x, new_y, new_width, new_height);
+}
+
+Point Rect::CenterPoint() const {
+ return Point(x() + (width() + 1) / 2, y() + (height() + 1) / 2);
+}
+
+bool Rect::SharesEdgeWith(const Rect& rect) const {
+ return (y() == rect.y() && height() == rect.height() &&
+ (x() == rect.right() || right() == rect.x())) ||
+ (x() == rect.x() && width() == rect.width() &&
+ (y() == rect.bottom() || bottom() == rect.y()));
+}
+
+} // namespace gfx
diff --git a/ppapi/cpp/rect.h b/ppapi/cpp/rect.h
new file mode 100644
index 0000000..7b133d2
--- /dev/null
+++ b/ppapi/cpp/rect.h
@@ -0,0 +1,213 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_RECT_H_
+#define PPAPI_CPP_RECT_H_
+
+#include "ppapi/c/pp_rect.h"
+#include "ppapi/cpp/point.h"
+#include "ppapi/cpp/size.h"
+
+namespace pp {
+
+class Rect {
+ public:
+ Rect() {
+ rect_.point.x = 0;
+ rect_.point.y = 0;
+ rect_.size.width = 0;
+ rect_.size.height = 0;
+ }
+ Rect(const PP_Rect& rect) { // Implicit.
+ set_x(rect.point.x);
+ set_y(rect.point.y);
+ set_width(rect.size.width);
+ set_height(rect.size.height);
+ }
+ Rect(int32_t w, int32_t h) {
+ set_x(0);
+ set_y(0);
+ set_width(w);
+ set_height(h);
+ }
+ Rect(int32_t x, int32_t y, int32_t w, int32_t h) {
+ set_x(x);
+ set_y(y);
+ set_width(w);
+ set_height(h);
+ }
+ explicit Rect(const Size& s) {
+ set_x(0);
+ set_y(0);
+ set_size(s);
+ }
+ Rect(const Point& origin, const Size& size) {
+ set_point(origin);
+ set_size(size);
+ }
+
+ ~Rect() {
+ }
+
+ operator PP_Rect() const {
+ return rect_;
+ }
+ const PP_Rect& pp_rect() const {
+ return rect_;
+ }
+ PP_Rect& pp_rect() {
+ return rect_;
+ }
+
+ int32_t x() const {
+ return rect_.point.x;
+ }
+ void set_x(int32_t in_x) {
+ rect_.point.x = in_x;
+ }
+
+ int32_t y() const {
+ return rect_.point.y;
+ }
+ void set_y(int32_t in_y) {
+ rect_.point.y = in_y;
+ }
+
+ int32_t width() const {
+ return rect_.size.width;
+ }
+ void set_width(int32_t w) {
+ if (w < 0) {
+ PP_DCHECK(w >= 0);
+ w = 0;
+ }
+ rect_.size.width = w;
+ }
+
+ int32_t height() const {
+ return rect_.size.height;
+ }
+ void set_height(int32_t h) {
+ if (h < 0) {
+ PP_DCHECK(h >= 0);
+ h = 0;
+ }
+ rect_.size.height = h;
+ }
+
+ Point point() const {
+ return Point(rect_.point);
+ }
+ void set_point(const Point& origin) {
+ rect_.point = origin;
+ }
+
+ Size size() const {
+ return Size(rect_.size);
+ }
+ void set_size(const Size& s) {
+ rect_.size.width = s.width();
+ rect_.size.height = s.height();
+ }
+
+ int32_t right() const {
+ return x() + width();
+ }
+ int32_t bottom() const {
+ return y() + height();
+ }
+
+ void SetRect(int32_t x, int32_t y, int32_t w, int32_t h) {
+ set_x(x);
+ set_y(y);
+ set_width(w);
+ set_height(h);
+ }
+ void SetRect(const PP_Rect& rect) {
+ rect_ = rect;
+ }
+
+ // Shrink the rectangle by a horizontal and vertical distance on all sides.
+ void Inset(int32_t horizontal, int32_t vertical) {
+ Inset(horizontal, vertical, horizontal, vertical);
+ }
+
+ // Shrink the rectangle by the specified amount on each side.
+ void Inset(int32_t left, int32_t top, int32_t right, int32_t bottom);
+
+ // Move the rectangle by a horizontal and vertical distance.
+ void Offset(int32_t horizontal, int32_t vertical);
+ void Offset(const Point& point) {
+ Offset(point.x(), point.y());
+ }
+
+ // Returns true if the area of the rectangle is zero.
+ bool IsEmpty() const {
+ return rect_.size.width == 0 && rect_.size.height == 0;
+ }
+
+ void swap(Rect& other);
+
+ // Returns true if the point identified by point_x and point_y falls inside
+ // this rectangle. The point (x, y) is inside the rectangle, but the
+ // point (x + width, y + height) is not.
+ bool Contains(int32_t point_x, int32_t point_y) const;
+
+ // Returns true if the specified point is contained by this rectangle.
+ bool Contains(const Point& point) const {
+ return Contains(point.x(), point.y());
+ }
+
+ // Returns true if this rectangle contains the specified rectangle.
+ bool Contains(const Rect& rect) const;
+
+ // Returns true if this rectangle int32_tersects the specified rectangle.
+ bool Intersects(const Rect& rect) const;
+
+ // Computes the int32_tersection of this rectangle with the given rectangle.
+ Rect Intersect(const Rect& rect) const;
+
+ // Computes the union of this rectangle with the given rectangle. The union
+ // is the smallest rectangle containing both rectangles.
+ Rect Union(const Rect& rect) const;
+
+ // Computes the rectangle resulting from subtracting |rect| from |this|. If
+ // |rect| does not intersect completely in either the x- or y-direction, then
+ // |*this| is returned. If |rect| contains |this|, then an empty Rect is
+ // returned.
+ Rect Subtract(const Rect& rect) const;
+
+ // Fits as much of the receiving rectangle int32_to the supplied rectangle as
+ // possible, returning the result. For example, if the receiver had
+ // a x-location of 2 and a width of 4, and the supplied rectangle had
+ // an x-location of 0 with a width of 5, the returned rectangle would have
+ // an x-location of 1 with a width of 4.
+ Rect AdjustToFit(const Rect& rect) const;
+
+ // Returns the center of this rectangle.
+ Point CenterPoint() const;
+
+ // Returns true if this rectangle shares an entire edge (i.e., same width or
+ // same height) with the given rectangle, and the rectangles do not overlap.
+ bool SharesEdgeWith(const Rect& rect) const;
+
+ private:
+ PP_Rect rect_;
+};
+
+} // namespace pp
+
+inline bool operator==(const pp::Rect& lhs, const pp::Rect& rhs) {
+ return lhs.x() == rhs.x() &&
+ lhs.y() == rhs.y() &&
+ lhs.width() == rhs.width() &&
+ lhs.height() == rhs.height();
+}
+
+inline bool operator!=(const pp::Rect& lhs, const pp::Rect& rhs) {
+ return !(lhs == rhs);
+}
+
+#endif
+
diff --git a/ppapi/cpp/resource.cc b/ppapi/cpp/resource.cc
new file mode 100644
index 0000000..e4a0d96
--- /dev/null
+++ b/ppapi/cpp/resource.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2010 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/resource.h"
+
+#include <algorithm>
+
+#include "ppapi/cpp/logging.h"
+#include "ppapi/cpp/module.h"
+
+namespace pp {
+
+Resource::Resource() : pp_resource_(0) {
+}
+
+Resource::Resource(const Resource& other) : pp_resource_(other.pp_resource_) {
+ if (!is_null())
+ Module::Get()->core()->AddRefResource(pp_resource_);
+}
+
+Resource::~Resource() {
+ if (!is_null())
+ Module::Get()->core()->ReleaseResource(pp_resource_);
+}
+
+Resource& Resource::operator=(const Resource& other) {
+ Resource copy(other);
+ swap(copy);
+ return *this;
+}
+
+void Resource::swap(Resource& other) {
+ std::swap(pp_resource_, other.pp_resource_);
+}
+
+PP_Resource Resource::detach() {
+ PP_Resource ret = pp_resource_;
+ pp_resource_ = 0;
+ return ret;
+}
+
+Resource::Resource(PP_Resource resource) : pp_resource_(resource) {
+ if (!is_null())
+ Module::Get()->core()->AddRefResource(pp_resource_);
+}
+
+void Resource::PassRefFromConstructor(PP_Resource resource) {
+ PP_DCHECK(!pp_resource_);
+ pp_resource_ = resource;
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/resource.h b/ppapi/cpp/resource.h
new file mode 100644
index 0000000..33e9982
--- /dev/null
+++ b/ppapi/cpp/resource.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_RESOURCE_H_
+#define PPAPI_CPP_RESOURCE_H_
+
+#include "ppapi/c/pp_resource.h"
+
+namespace pp {
+
+// Base class for refcounted plugin resources.
+class Resource {
+ public:
+ Resource();
+ Resource(const Resource& other);
+
+ virtual ~Resource();
+
+ Resource& operator=(const Resource& other);
+ void swap(Resource& other);
+
+ // Returns true if the given resource is invalid or uninitialized.
+ bool is_null() const { return !pp_resource_; }
+
+ PP_Resource pp_resource() const { return pp_resource_; }
+
+ // Releases ownership of the PP_Resource and returns it to the caller.
+ // Note the the reference count on the resource is unchanged and the caller
+ // needs to release the resource.
+ PP_Resource detach();
+
+ protected:
+ // This constructor is used when we've gotten a PP_Resource as a return value
+ // that we need to addref.
+ explicit Resource(PP_Resource resource);
+
+ // Called by derived class' constructors to initialize this Resource with
+ // a PP_Resource that has already been AddRef'ed. It also assumes this object
+ // has no current resource.
+ //
+ // The intended usage is that the derived class constructor will call the
+ // default Resource constructor, then make a call to create a resource. It
+ // then wants to assign the new resource (which, since it was returned by the
+ // browser, is already AddRef'ed).
+ void PassRefFromConstructor(PP_Resource resource);
+
+ private:
+ PP_Resource pp_resource_;
+};
+
+} // namespace pp
+
+inline bool operator==(const pp::Resource& lhs, const pp::Resource& rhs) {
+ return lhs.pp_resource() == rhs.pp_resource();
+}
+
+#endif // PPAPI_CPP_RESOURCE_H_
diff --git a/ppapi/cpp/size.h b/ppapi/cpp/size.h
new file mode 100644
index 0000000..adcaf78
--- /dev/null
+++ b/ppapi/cpp/size.h
@@ -0,0 +1,108 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_SIZE_H_
+#define PPAPI_CPP_SIZE_H_
+
+#include "ppapi/c/pp_size.h"
+#include "ppapi/cpp/logging.h"
+
+namespace pp {
+
+class Size {
+ public:
+ Size() {
+ size_.width = 0;
+ size_.height = 0;
+ }
+ Size(const PP_Size& s) { // Implicit.
+ // Want the >= 0 checking of the setter.
+ set_width(s.width);
+ set_height(s.height);
+ }
+ Size(int w, int h) {
+ // Want the >= 0 checking of the setter.
+ set_width(w);
+ set_height(h);
+ }
+
+ ~Size() {
+ }
+
+ operator PP_Size() {
+ return size_;
+ }
+ const PP_Size& pp_size() const {
+ return size_;
+ }
+ PP_Size& pp_size() {
+ return size_;
+ }
+
+ int width() const {
+ return size_.width;
+ }
+ void set_width(int w) {
+ if (w < 0) {
+ PP_DCHECK(w >= 0);
+ w = 0;
+ }
+ size_.width = w;
+ }
+
+ int height() const {
+ return size_.height;
+ }
+ void set_height(int h) {
+ if (h < 0) {
+ PP_DCHECK(h >= 0);
+ h = 0;
+ }
+ size_.height = h;
+ }
+
+ int GetArea() const {
+ return width() * height();
+ }
+
+ void SetSize(int w, int h) {
+ set_width(w);
+ set_height(h);
+ }
+
+ void Enlarge(int w, int h) {
+ set_width(width() + w);
+ set_height(height() + h);
+ }
+
+ void swap(Size& other) {
+ int32_t w = size_.width;
+ int32_t h = size_.height;
+ size_.width = other.size_.width;
+ size_.height = other.size_.height;
+ other.size_.width = w;
+ other.size_.height = h;
+ }
+
+ bool IsEmpty() const {
+ // Size doesn't allow negative dimensions, so testing for 0 is enough.
+ return (width() == 0) || (height() == 0);
+ }
+
+ private:
+ PP_Size size_;
+};
+
+} // namespace pp
+
+inline bool operator==(const pp::Size& lhs, const pp::Size& rhs) {
+ return lhs.width() == rhs.width() && lhs.height() == rhs.height();
+}
+
+inline bool operator!=(const pp::Size& lhs, const pp::Size& rhs) {
+ return !(lhs == rhs);
+}
+
+#endif // PPAPI_CPP_SIZE_H_
+
diff --git a/ppapi/cpp/var.cc b/ppapi/cpp/var.cc
new file mode 100644
index 0000000..d48253a
--- /dev/null
+++ b/ppapi/cpp/var.cc
@@ -0,0 +1,365 @@
+// Copyright (c) 2010 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/var.h"
+
+#include <string.h>
+
+#include <algorithm>
+
+#include "ppapi/c/pp_var.h"
+#include "ppapi/c/dev/ppb_var_deprecated.h"
+#include "ppapi/cpp/logging.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/module_impl.h"
+#include "ppapi/cpp/dev/scriptable_object_deprecated.h"
+
+// Defining snprintf
+#include <stdio.h>
+#if defined(_MSC_VER)
+# define snprintf _snprintf_s
+#endif
+
+namespace {
+
+DeviceFuncs<PPB_Var_Deprecated> ppb_var_f(PPB_VAR_DEPRECATED_INTERFACE);
+
+// Technically you can call AddRef and Release on any Var, but it may involve
+// cross-process calls depending on the plugin. This is an optimization so we
+// only do refcounting on the necessary objects.
+inline bool NeedsRefcounting(const PP_Var& var) {
+ return var.type == PP_VARTYPE_STRING || var.type == PP_VARTYPE_OBJECT;
+}
+
+} // namespace
+
+namespace pp {
+
+using namespace deprecated;
+
+Var::Var() {
+ var_.type = PP_VARTYPE_UNDEFINED;
+ needs_release_ = false;
+}
+
+Var::Var(Null) {
+ var_.type = PP_VARTYPE_NULL;
+ needs_release_ = false;
+}
+
+Var::Var(bool b) {
+ var_.type = PP_VARTYPE_BOOL;
+ var_.value.as_bool = b;
+ needs_release_ = false;
+}
+
+Var::Var(int32_t i) {
+ var_.type = PP_VARTYPE_INT32;
+ var_.value.as_int = i;
+ needs_release_ = false;
+}
+
+Var::Var(double d) {
+ var_.type = PP_VARTYPE_DOUBLE;
+ var_.value.as_double = d;
+ needs_release_ = false;
+}
+
+Var::Var(const char* utf8_str) {
+ if (ppb_var_f) {
+ uint32_t len = utf8_str ? static_cast<uint32_t>(strlen(utf8_str)) : 0;
+ var_ = ppb_var_f->VarFromUtf8(Module::Get()->pp_module(), utf8_str, len);
+ } else {
+ var_.type = PP_VARTYPE_NULL;
+ }
+ needs_release_ = (var_.type == PP_VARTYPE_STRING);
+}
+
+Var::Var(const std::string& utf8_str) {
+ if (ppb_var_f) {
+ var_ = ppb_var_f->VarFromUtf8(Module::Get()->pp_module(),
+ utf8_str.c_str(),
+ static_cast<uint32_t>(utf8_str.size()));
+ } else {
+ var_.type = PP_VARTYPE_NULL;
+ }
+ needs_release_ = (var_.type == PP_VARTYPE_STRING);
+}
+
+Var::Var(ScriptableObject* object) {
+ if (ppb_var_f) {
+ var_ = ppb_var_f->CreateObject(Module::Get()->pp_module(),
+ object->GetClass(), object);
+ needs_release_ = true;
+ } else {
+ var_.type = PP_VARTYPE_NULL;
+ needs_release_ = false;
+ }
+}
+
+Var::Var(const Var& other) {
+ var_ = other.var_;
+ if (NeedsRefcounting(var_)) {
+ if (ppb_var_f) {
+ needs_release_ = true;
+ ppb_var_f->AddRef(var_);
+ } else {
+ var_.type = PP_VARTYPE_NULL;
+ needs_release_ = false;
+ }
+ } else {
+ needs_release_ = false;
+ }
+}
+
+Var::~Var() {
+ if (needs_release_ && ppb_var_f)
+ ppb_var_f->Release(var_);
+}
+
+Var& Var::operator=(const Var& other) {
+ if (needs_release_ && ppb_var_f)
+ ppb_var_f->Release(var_);
+ var_ = other.var_;
+ if (NeedsRefcounting(var_)) {
+ if (ppb_var_f) {
+ needs_release_ = true;
+ ppb_var_f->AddRef(var_);
+ } else {
+ var_.type = PP_VARTYPE_NULL;
+ needs_release_ = false;
+ }
+ } else {
+ needs_release_ = false;
+ }
+ return *this;
+}
+
+bool Var::operator==(const Var& other) const {
+ if (var_.type != other.var_.type)
+ return false;
+ switch (var_.type) {
+ case PP_VARTYPE_UNDEFINED:
+ case PP_VARTYPE_NULL:
+ return true;
+ case PP_VARTYPE_BOOL:
+ return AsBool() == other.AsBool();
+ case PP_VARTYPE_INT32:
+ return AsInt() == other.AsInt();
+ case PP_VARTYPE_DOUBLE:
+ return AsDouble() == other.AsDouble();
+ case PP_VARTYPE_STRING:
+ if (var_.value.as_id == other.var_.value.as_id)
+ return true;
+ return AsString() == other.AsString();
+ // TODO(neb): Document that this is === and not ==, unlike strings.
+ case PP_VARTYPE_OBJECT:
+ return var_.value.as_id == other.var_.value.as_id;
+ default:
+ return false;
+ }
+}
+
+bool Var::AsBool() const {
+ if (!is_bool()) {
+ PP_NOTREACHED();
+ return false;
+ }
+ return var_.value.as_bool;
+}
+
+int32_t Var::AsInt() const {
+ if (is_int())
+ return var_.value.as_int;
+ if (is_double())
+ return static_cast<int>(var_.value.as_double);
+ PP_NOTREACHED();
+ return 0;
+}
+
+double Var::AsDouble() const {
+ if (is_double())
+ return var_.value.as_double;
+ if (is_int())
+ return static_cast<double>(var_.value.as_int);
+ PP_NOTREACHED();
+ return 0.0;
+}
+
+std::string Var::AsString() const {
+ if (!is_string()) {
+ PP_NOTREACHED();
+ return std::string();
+ }
+
+ if (!ppb_var_f)
+ return std::string();
+ uint32_t len;
+ const char* str = ppb_var_f->VarToUtf8(var_, &len);
+ return std::string(str, len);
+}
+
+ScriptableObject* Var::AsScriptableObject() const {
+ if (!is_object()) {
+ PP_NOTREACHED();
+ } else if (ppb_var_f) {
+ void* object = NULL;
+ if (ppb_var_f->IsInstanceOf(var_, ScriptableObject::GetClass(), &object)) {
+ return reinterpret_cast<ScriptableObject*>(object);
+ }
+ }
+ return NULL;
+}
+
+bool Var::HasProperty(const Var& name, Var* exception) const {
+ if (!ppb_var_f)
+ return false;
+ return ppb_var_f->HasProperty(var_, name.var_, OutException(exception).get());
+}
+
+bool Var::HasMethod(const Var& name, Var* exception) const {
+ if (!ppb_var_f)
+ return false;
+ return ppb_var_f->HasMethod(var_, name.var_, OutException(exception).get());
+}
+
+Var Var::GetProperty(const Var& name, Var* exception) const {
+ if (!ppb_var_f)
+ return Var();
+ return Var(PassRef(), ppb_var_f->GetProperty(var_, name.var_,
+ OutException(exception).get()));
+}
+
+void Var::GetAllPropertyNames(std::vector<Var>* properties,
+ Var* exception) const {
+ if (!ppb_var_f)
+ return;
+ PP_Var* props = NULL;
+ uint32_t prop_count = 0;
+ ppb_var_f->GetAllPropertyNames(var_, &prop_count, &props,
+ OutException(exception).get());
+ if (!prop_count)
+ return;
+ properties->resize(prop_count);
+ for (uint32_t i = 0; i < prop_count; ++i) {
+ Var temp(PassRef(), props[i]);
+ (*properties)[i] = temp;
+ }
+ Module::Get()->core()->MemFree(props);
+}
+
+void Var::SetProperty(const Var& name, const Var& value, Var* exception) {
+ if (!ppb_var_f)
+ return;
+ ppb_var_f->SetProperty(var_, name.var_, value.var_,
+ OutException(exception).get());
+}
+
+void Var::RemoveProperty(const Var& name, Var* exception) {
+ if (!ppb_var_f)
+ return;
+ ppb_var_f->RemoveProperty(var_, name.var_, OutException(exception).get());
+}
+
+Var Var::Call(const Var& method_name, uint32_t argc, Var* argv,
+ Var* exception) {
+ if (!ppb_var_f)
+ return Var();
+ if (argc > 0) {
+ std::vector<PP_Var> args;
+ args.reserve(argc);
+ for (size_t i = 0; i < argc; i++)
+ args.push_back(argv[i].var_);
+ return Var(PassRef(), ppb_var_f->Call(var_, method_name.var_,
+ argc, &args[0],
+ OutException(exception).get()));
+ } else {
+ // Don't try to get the address of a vector if it's empty.
+ return Var(PassRef(), ppb_var_f->Call(var_, method_name.var_, 0, NULL,
+ OutException(exception).get()));
+ }
+}
+
+Var Var::Construct(uint32_t argc, Var* argv, Var* exception) const {
+ if (!ppb_var_f)
+ return Var();
+ if (argc > 0) {
+ std::vector<PP_Var> args;
+ args.reserve(argc);
+ for (size_t i = 0; i < argc; i++)
+ args.push_back(argv[i].var_);
+ return Var(PassRef(), ppb_var_f->Construct(var_, argc, &args[0],
+ OutException(exception).get()));
+ } else {
+ // Don't try to get the address of a vector if it's empty.
+ return Var(PassRef(), ppb_var_f->Construct(var_, 0, NULL,
+ OutException(exception).get()));
+ }
+}
+
+Var Var::Call(const Var& method_name, Var* exception) {
+ if (!ppb_var_f)
+ return Var();
+ return Var(PassRef(), ppb_var_f->Call(var_, method_name.var_, 0, NULL,
+ OutException(exception).get()));
+}
+
+Var Var::Call(const Var& method_name, const Var& arg1, Var* exception) {
+ if (!ppb_var_f)
+ return Var();
+ PP_Var args[1] = {arg1.var_};
+ return Var(PassRef(), ppb_var_f->Call(var_, method_name.var_, 1, args,
+ OutException(exception).get()));
+}
+
+Var Var::Call(const Var& method_name, const Var& arg1, const Var& arg2,
+ Var* exception) {
+ if (!ppb_var_f)
+ return Var();
+ PP_Var args[2] = {arg1.var_, arg2.var_};
+ return Var(PassRef(), ppb_var_f->Call(var_, method_name.var_, 2, args,
+ OutException(exception).get()));
+}
+
+Var Var::Call(const Var& method_name, const Var& arg1, const Var& arg2,
+ const Var& arg3, Var* exception) {
+ if (!ppb_var_f)
+ return Var();
+ PP_Var args[3] = {arg1.var_, arg2.var_, arg3.var_};
+ return Var(PassRef(), ppb_var_f->Call(var_, method_name.var_, 3, args,
+ OutException(exception).get()));
+}
+
+Var Var::Call(const Var& method_name, const Var& arg1, const Var& arg2,
+ const Var& arg3, const Var& arg4, Var* exception) {
+ if (!ppb_var_f)
+ return Var();
+ PP_Var args[4] = {arg1.var_, arg2.var_, arg3.var_, arg4.var_};
+ return Var(PassRef(), ppb_var_f->Call(var_, method_name.var_, 4, args,
+ OutException(exception).get()));
+}
+
+std::string Var::DebugString() const {
+ char buf[256];
+ if (is_undefined())
+ snprintf(buf, sizeof(buf), "Var<UNDEFINED>");
+ else if (is_null())
+ snprintf(buf, sizeof(buf), "Var<NULL>");
+ else if (is_bool())
+ snprintf(buf, sizeof(buf), AsBool() ? "Var<true>" : "Var<false>");
+ else if (is_int())
+ // Note that the following static_cast is necessary because
+ // NativeClient's int32_t is actually "long".
+ // TODO(sehr,polina): remove this after newlib is changed.
+ snprintf(buf, sizeof(buf), "Var<%d>", static_cast<int>(AsInt()));
+ else if (is_double())
+ snprintf(buf, sizeof(buf), "Var<%f>", AsDouble());
+ else if (is_string())
+ snprintf(buf, sizeof(buf), "Var<'%s'>", AsString().c_str());
+ else if (is_object())
+ snprintf(buf, sizeof(buf), "Var<OBJECT>");
+ return buf;
+}
+
+} // namespace pp
diff --git a/ppapi/cpp/var.h b/ppapi/cpp/var.h
new file mode 100644
index 0000000..9109fef
--- /dev/null
+++ b/ppapi/cpp/var.h
@@ -0,0 +1,205 @@
+// Copyright (c) 2010 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.
+
+#ifndef PPAPI_CPP_VAR_H_
+#define PPAPI_CPP_VAR_H_
+
+#include <string>
+#include <vector>
+
+#include "ppapi/c/pp_var.h"
+
+namespace pp {
+
+namespace deprecated {
+class ScriptableObject;
+}
+
+class Var {
+ public:
+ struct Null {}; // Special value passed to constructor to make NULL.
+
+ Var(); // PP_Var of type Undefined.
+ Var(Null); // PP_Var of type Null.
+ Var(bool b);
+ Var(int32_t i);
+ Var(double d);
+ Var(const char* utf8_str); // Must be encoded in UTF-8.
+ Var(const std::string& utf8_str); // Must be encoded in UTF-8.
+
+ // This magic constructor is used when we've gotten a PP_Var as a return
+ // value that has already been addref'ed for us.
+ struct PassRef {};
+ Var(PassRef, PP_Var var) {
+ var_ = var;
+ needs_release_ = true;
+ }
+
+ // TODO(brettw): remove DontManage when this bug is fixed
+ // http://code.google.com/p/chromium/issues/detail?id=52105
+ // This magic constructor is used when we've given a PP_Var as an input
+ // argument from somewhere and that reference is managing the reference
+ // count for us. The object will not be AddRef'ed or Release'd by this
+ // class instance..
+ struct DontManage {};
+ Var(DontManage, PP_Var var) {
+ var_ = var;
+ needs_release_ = false;
+ }
+
+ // Takes ownership of the given pointer.
+ Var(deprecated::ScriptableObject* object);
+
+ Var(const Var& other);
+
+ virtual ~Var();
+
+ Var& operator=(const Var& other);
+
+ bool operator==(const Var& other) const;
+
+ bool is_undefined() const { return var_.type == PP_VARTYPE_UNDEFINED; }
+ bool is_null() const { return var_.type == PP_VARTYPE_NULL; }
+ bool is_bool() const { return var_.type == PP_VARTYPE_BOOL; }
+ bool is_string() const { return var_.type == PP_VARTYPE_STRING; }
+ bool is_object() const { return var_.type == PP_VARTYPE_OBJECT; }
+
+ // IsInt and IsDouble return the internal representation. The JavaScript
+ // runtime may convert between the two as needed, so the distinction may
+ // not be relevant in all cases (int is really an optimization inside the
+ // runtime). So most of the time, you will want to check IsNumber.
+ bool is_int() const { return var_.type == PP_VARTYPE_INT32; }
+ bool is_double() const { return var_.type == PP_VARTYPE_DOUBLE; }
+ bool is_number() const {
+ return var_.type == PP_VARTYPE_INT32 ||
+ var_.type == PP_VARTYPE_DOUBLE;
+ }
+
+ // Assumes the internal representation IsBool. If it's not, it will assert
+ // in debug mode, and return false.
+ bool AsBool() const;
+
+ // AsInt and AsDouble implicitly convert between ints and doubles. This is
+ // because JavaScript doesn't have a concept of ints and doubles, only
+ // numbers. The distinction between the two is an optimization inside the
+ // compiler. Since converting from a double to an int may be lossy, if you
+ // care about the distinction, either always work in doubles, or check
+ // !IsDouble() before calling AsInt().
+ //
+ // These functions will assert in debug mode and return 0 if the internal
+ // representation is not IsNumber().
+ int32_t AsInt() const;
+ double AsDouble() const;
+
+ // This assumes the object is of type string. If it's not, it will assert
+ // in debug mode, and return an empty string.
+ std::string AsString() const;
+
+ // This assumes the object is of type object. If it's not, it will assert in
+ // debug mode. If it is not an object or not a ScriptableObject type, returns
+ // NULL.
+ deprecated::ScriptableObject* AsScriptableObject() const;
+
+ bool HasProperty(const Var& name, Var* exception = NULL) const;
+ bool HasMethod(const Var& name, Var* exception = NULL) const;
+ Var GetProperty(const Var& name, Var* exception = NULL) const;
+ void GetAllPropertyNames(std::vector<Var>* properties,
+ Var* exception = NULL) const;
+ void SetProperty(const Var& name, const Var& value, Var* exception = NULL);
+ void RemoveProperty(const Var& name, Var* exception = NULL);
+ Var Call(const Var& method_name, uint32_t argc, Var* argv,
+ Var* exception = NULL);
+ Var Construct(uint32_t argc, Var* argv, Var* exception = NULL) const;
+
+ // Convenience functions for calling functions with small # of args.
+ Var Call(const Var& method_name, Var* exception = NULL);
+ Var Call(const Var& method_name, const Var& arg1, Var* exception = NULL);
+ Var Call(const Var& method_name, const Var& arg1, const Var& arg2,
+ Var* exception = NULL);
+ Var Call(const Var& method_name, const Var& arg1, const Var& arg2,
+ const Var& arg3, Var* exception = NULL);
+ Var Call(const Var& method_name, const Var& arg1, const Var& arg2,
+ const Var& arg3, const Var& arg4, Var* exception = NULL);
+
+ // Returns a const reference to the PP_Var managed by this Var object.
+ const PP_Var& pp_var() const {
+ return var_;
+ }
+
+ // Detaches from the internal PP_Var of this object, keeping the reference
+ // count the same. This is used when returning a PP_Var from an API function
+ // where the caller expects the return value to be AddRef'ed for it.
+ PP_Var Detach() {
+ PP_Var ret = var_;
+ var_ = PP_MakeUndefined();
+ needs_release_ = false;
+ return ret;
+ }
+
+ // Prints a short description "Var<X>" that can be used for logging, where
+ // "X" is the underlying scalar or "UNDEFINED" or "OBJ" as it does not call
+ // into the browser to get the object description.
+ std::string DebugString() const;
+
+ // For use when calling the raw C PPAPI when using the C++ Var as a possibly
+ // NULL exception. This will handle getting the address of the internal value
+ // out if it's non-NULL and fixing up the reference count.
+ //
+ // Danger: this will only work for things with exception semantics, i.e. that
+ // the value will not be changed if it's a non-undefined exception. Otherwise,
+ // this class will mess up the refcounting.
+ //
+ // This is a bit subtle:
+ // - If NULL is passed, we return NULL from get() and do nothing.
+ //
+ // - If a undefined value is passed, we return the address of a undefined var
+ // from get and have the output value take ownership of that var.
+ //
+ // - If a non-undefined value is passed, we return the address of that var
+ // from get, and nothing else should change.
+ //
+ // Example:
+ // void FooBar(a, b, Var* exception = NULL) {
+ // foo_interface->Bar(a, b, Var::OutException(exception).get());
+ // }
+ class OutException {
+ public:
+ OutException(Var* v)
+ : output_(v),
+ originally_had_exception_(v && v->is_null()) {
+ if (output_)
+ temp_ = output_->var_;
+ else
+ temp_.type = PP_VARTYPE_UNDEFINED;
+ }
+ ~OutException() {
+ if (output_ && !originally_had_exception_)
+ *output_ = Var(PassRef(), temp_);
+ }
+
+ PP_Var* get() {
+ if (output_)
+ return &temp_;
+ return NULL;
+ }
+
+ private:
+ Var* output_;
+ bool originally_had_exception_;
+ PP_Var temp_;
+ };
+
+ private:
+ // Prevent an arbitrary pointer argument from being implicitly converted to
+ // a bool at Var construction. If somebody makes such a mistake, (s)he will
+ // get a compilation error.
+ Var(void* non_scriptable_object_pointer);
+
+ PP_Var var_;
+ bool needs_release_;
+};
+
+} // namespace pp
+
+#endif // PPAPI_CPP_VAR_H_