diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-01 16:16:50 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-01 16:16:50 +0000 |
commit | 1758e88fd909ea0ffd49621e8066ffad5627ffdf (patch) | |
tree | c304a5eed047cae5665f5af1739d84655fb5815d /ppapi/cpp | |
parent | e7d8b51953b7d3b2b8a0aba46132305b32f3efce (diff) | |
download | chromium_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')
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_ |