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/example | |
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/example')
-rw-r--r-- | ppapi/example/Info.plist | 46 | ||||
-rw-r--r-- | ppapi/example/example.cc | 426 | ||||
-rw-r--r-- | ppapi/example/example.html | 17 | ||||
-rw-r--r-- | ppapi/example/example.rc | 30 | ||||
-rw-r--r-- | ppapi/example/example_framed.html | 2 |
5 files changed, 521 insertions, 0 deletions
diff --git a/ppapi/example/Info.plist b/ppapi/example/Info.plist new file mode 100644 index 0000000..7925b7f --- /dev/null +++ b/ppapi/example/Info.plist @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>${EXECUTABLE_NAME}</string> + <key>CFBundleGetInfoString</key> + <string>Copyright 2010 Google, Inc.</string> + <key>CFBundleIdentifier</key> + <string>com.google.exampleplugin</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundlePackageType</key> + <string>BRPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1.0</string> + <key>CFPlugInDynamicRegisterFunction</key> + <string></string> + <key>CFPlugInDynamicRegistration</key> + <string>NO</string> + <key>WebPluginDescription</key> + <string>Simple Pepper plug-in that handles tests</string> + <key>WebPluginMIMETypes</key> + <dict> + <key>pepper-application/x-pepper-example-plugin</key> + <dict> + <key>WebPluginExtensions</key> + <array> + <string>testpepper</string> + </array> + <key>WebPluginTypeDescription</key> + <string>Test Pepper API</string> + </dict> + </dict> + <key>WebPluginName</key> + <string>Pepper Test PlugIn</string> +</dict> +</plist> diff --git a/ppapi/example/example.cc b/ppapi/example/example.cc new file mode 100644 index 0000000..bb3825f --- /dev/null +++ b/ppapi/example/example.cc @@ -0,0 +1,426 @@ +// 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 <math.h> +#include <stdio.h> // FIXME(brettw) erase me. +#ifndef _WIN32 +#include <sys/time.h> +#endif +#include <time.h> + +#include <algorithm> + +#include "ppapi/c/dev/ppp_printing_dev.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_input_event.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/dev/scriptable_object_deprecated.h" +#include "ppapi/cpp/dev/url_loader_dev.h" +#include "ppapi/cpp/dev/url_request_info_dev.h" +#include "ppapi/cpp/graphics_2d.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/var.h" + +static const int kStepsPerCircle = 800; + +void FlushCallback(void* data, int32_t result); + +void FillRect(pp::ImageData* image, int left, int top, int width, int height, + uint32_t color) { + for (int y = std::max(0, top); + y < std::min(image->size().height() - 1, top + height); + y++) { + for (int x = std::max(0, left); + x < std::min(image->size().width() - 1, left + width); + x++) + *image->GetAddr32(pp::Point(x, y)) = color; + } +} + +class MyScriptableObject : public pp::deprecated::ScriptableObject { + public: + virtual bool HasMethod(const pp::Var& method, pp::Var* exception) { + return method.AsString() == "toString"; + } + + virtual bool HasProperty(const pp::Var& name, pp::Var* exception) { + if (name.is_string() && name.AsString() == "blah") + return true; + return false; + } + + virtual pp::Var GetProperty(const pp::Var& name, pp::Var* exception) { + if (name.is_string() && name.AsString() == "blah") + return new MyScriptableObject(); + return pp::Var(); + } + + virtual void GetAllPropertyNames(std::vector<pp::Var>* names, + pp::Var* exception) { + names->push_back("blah"); + } + + virtual pp::Var Call(const pp::Var& method, + const std::vector<pp::Var>& args, + pp::Var* exception) { + if (method.AsString() == "toString") + return pp::Var("hello world"); + return pp::Var(); + } +}; + +class MyFetcherClient { + public: + virtual void DidFetch(bool success, const std::string& data) = 0; +}; + +class MyFetcher { + public: + MyFetcher() : client_(NULL) { + callback_factory_.Initialize(this); + } + + void Start(const pp::Instance& instance, + const pp::Var& url, + MyFetcherClient* client) { + pp::URLRequestInfo_Dev request; + request.SetURL(url); + request.SetMethod("GET"); + + loader_ = pp::URLLoader_Dev(instance); + client_ = client; + + pp::CompletionCallback callback = + callback_factory_.NewCallback(&MyFetcher::DidOpen); + int rv = loader_.Open(request, callback); + if (rv != PP_ERROR_WOULDBLOCK) + callback.Run(rv); + } + + void StartWithOpenedLoader(const pp::URLLoader_Dev& loader, + MyFetcherClient* client) { + loader_ = loader; + client_ = client; + + ReadMore(); + } + + private: + void ReadMore() { + pp::CompletionCallback callback = + callback_factory_.NewCallback(&MyFetcher::DidRead); + int rv = loader_.ReadResponseBody(buf_, sizeof(buf_), callback); + if (rv != PP_ERROR_WOULDBLOCK) + callback.Run(rv); + } + + void DidOpen(int32_t result) { + if (result == PP_OK) { + ReadMore(); + } else { + DidFinish(result); + } + } + + void DidRead(int32_t result) { + if (result > 0) { + data_.append(buf_, result); + ReadMore(); + } else { + DidFinish(result); + } + } + + void DidFinish(int32_t result) { + if (client_) + client_->DidFetch(result == PP_OK, data_); + } + + pp::CompletionCallbackFactory<MyFetcher> callback_factory_; + pp::URLLoader_Dev loader_; + MyFetcherClient* client_; + char buf_[4096]; + std::string data_; +}; + +class MyInstance : public pp::Instance, public MyFetcherClient { + public: + MyInstance(PP_Instance instance) + : pp::Instance(instance), + time_at_last_check_(0.0), + fetcher_(NULL), + width_(0), + height_(0), + animation_counter_(0), + print_settings_valid_(false) {} + + virtual ~MyInstance() { + if (fetcher_) { + delete fetcher_; + fetcher_ = NULL; + } + } + + virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { + return true; + } + + virtual bool HandleDocumentLoad(const pp::URLLoader_Dev& loader) { + fetcher_ = new MyFetcher(); + fetcher_->StartWithOpenedLoader(loader, this); + return true; + } + + virtual bool HandleInputEvent(const PP_InputEvent& event) { + switch (event.type) { + case PP_INPUTEVENT_TYPE_MOUSEDOWN: + //SayHello(); + return true; + case PP_INPUTEVENT_TYPE_MOUSEMOVE: + return true; + case PP_INPUTEVENT_TYPE_KEYDOWN: + return true; + default: + return false; + } + } + + virtual pp::Var GetInstanceObject() { + return new MyScriptableObject(); + } + + pp::ImageData PaintImage(int width, int height) { + pp::ImageData image(PP_IMAGEDATAFORMAT_BGRA_PREMUL, + pp::Size(width, height), false); + if (image.is_null()) { + printf("Couldn't allocate the image data\n"); + return image; + } + + // Fill with semitransparent gradient. + for (int y = 0; y < image.size().height(); y++) { + char* row = &static_cast<char*>(image.data())[y * image.stride()]; + for (int x = 0; x < image.size().width(); x++) { + row[x * 4 + 0] = y; + row[x * 4 + 1] = y; + row[x * 4 + 2] = 0; + row[x * 4 + 3] = y; + } + } + + float radians = static_cast<float>(animation_counter_) / kStepsPerCircle * + 2 * 3.14159265358979F; + + float radius = static_cast<float>(std::min(width, height)) / 2.0f - 3.0f; + int x = static_cast<int>(cos(radians) * radius + radius + 2); + int y = static_cast<int>(sin(radians) * radius + radius + 2); + + FillRect(&image, x - 3, y - 3, 7, 7, 0x80000000); + return image; + } + + void Paint() { + pp::ImageData image = PaintImage(width_, height_); + if (!image.is_null()) { + device_context_.ReplaceContents(&image); + device_context_.Flush(pp::CompletionCallback(&FlushCallback, this)); + } + } + + virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) { + if (position.size().width() == width_ && + position.size().height() == height_) + return; // We don't care about the position, only the size. + + width_ = position.size().width(); + height_ = position.size().height(); + + device_context_ = pp::Graphics2D(pp::Size(width_, height_), false); + if (!BindGraphics(device_context_)) { + printf("Couldn't bind the device context\n"); + return; + } + + Paint(); + } + + void UpdateFps() { +// Time code doesn't currently compile on Windows, just skip FPS for now. +#ifndef _WIN32 + pp::Var window = GetWindowObject(); + pp::Var doc = window.GetProperty("document"); + pp::Var fps = doc.Call("getElementById", "fps"); + + struct timeval tv; + struct timezone tz = {0, 0}; + gettimeofday(&tv, &tz); + + double time_now = tv.tv_sec + tv.tv_usec / 1000000.0; + + if (animation_counter_ > 0) { + char fps_text[64]; + sprintf(fps_text, "%g fps", + kStepsPerCircle / (time_now - time_at_last_check_)); + fps.SetProperty("innerHTML", fps_text); + } + + time_at_last_check_ = time_now; +#endif + } + + // Print interfaces. + virtual PP_PrintOutputFormat_Dev* QuerySupportedPrintOutputFormats( + uint32_t* format_count) { + PP_PrintOutputFormat_Dev* format = + reinterpret_cast<PP_PrintOutputFormat_Dev*>( + pp::Module::Get()->core()->MemAlloc( + sizeof(PP_PrintOutputFormat_Dev))); + *format = PP_PRINTOUTPUTFORMAT_RASTER; + *format_count = 1; + return format; + } + + virtual int32_t PrintBegin(const PP_PrintSettings_Dev& print_settings) { + if (print_settings_.format != PP_PRINTOUTPUTFORMAT_RASTER) + return 0; + + print_settings_ = print_settings; + print_settings_valid_ = true; + return 1; + } + + virtual pp::Resource PrintPages( + const PP_PrintPageNumberRange_Dev* page_ranges, + uint32_t page_range_count) { + if (!print_settings_valid_) + return pp::Resource(); + + if (page_range_count != 1) + return pp::Resource(); + + // Check if the page numbers are valid. We returned 1 in PrintBegin so we + // only have 1 page to print. + if (page_ranges[0].first_page_number || page_ranges[0].last_page_number) { + return pp::Resource(); + } + + int width = static_cast<int>( + (print_settings_.printable_area.size.width / 72.0) * + print_settings_.dpi); + int height = static_cast<int>( + (print_settings_.printable_area.size.height / 72.0) * + print_settings_.dpi); + + return PaintImage(width, height); + } + + virtual void PrintEnd() { + print_settings_valid_ = false; + } + + void OnFlush() { + if (animation_counter_ % kStepsPerCircle == 0) + UpdateFps(); + animation_counter_++; + Paint(); + } + + private: + void Log(const pp::Var& var) { + pp::Var doc = GetWindowObject().GetProperty("document"); + if (console_.is_undefined()) { + pp::Var body = doc.GetProperty("body"); + console_ = doc.Call("createElement", "pre"); + console_.GetProperty("style").SetProperty("backgroundColor", "lightgray"); + body.Call("appendChild", console_); + } + console_.Call("appendChild", doc.Call("createTextNode", var)); + console_.Call("appendChild", doc.Call("createTextNode", "\n")); + } + + void SayHello() { + pp::Var window = GetWindowObject(); + pp::Var doc = window.GetProperty("document"); + pp::Var body = doc.GetProperty("body"); + + pp::Var obj(new MyScriptableObject()); + + // Our object should have its toString method called. + Log("Testing MyScriptableObject::toString():"); + Log(obj); + + // body.appendChild(body) should throw an exception + Log("\nCalling body.appendChild(body):"); + pp::Var exception; + body.Call("appendChild", body, &exception); + Log(exception); + + Log("\nEnumeration of window properties:"); + std::vector<pp::Var> props; + window.GetAllPropertyNames(&props); + for (size_t i = 0; i < props.size(); ++i) + Log(props[i]); + + pp::Var location = window.GetProperty("location"); + pp::Var href = location.GetProperty("href"); + + if (!fetcher_) { + fetcher_ = new MyFetcher(); + fetcher_->Start(*this, href, this); + } + } + + void DidFetch(bool success, const std::string& data) { + Log("\nDownloaded location.href:"); + if (success) { + Log(data); + } else { + Log("Failed to download."); + } + delete fetcher_; + fetcher_ = NULL; + } + + pp::Var console_; + pp::Graphics2D device_context_; + + double time_at_last_check_; + + MyFetcher* fetcher_; + + int width_; + int height_; + + // Incremented for each flush we get. + int animation_counter_; + bool print_settings_valid_; + PP_PrintSettings_Dev print_settings_; +}; + +void FlushCallback(void* data, int32_t result) { + static_cast<MyInstance*>(data)->OnFlush(); +} + +class MyModule : public pp::Module { + public: + MyModule() : pp::Module() {} + virtual ~MyModule() {} + + virtual pp::Instance* CreateInstance(PP_Instance instance) { + return new MyInstance(instance); + } +}; + +namespace pp { + +// Factory function for your specialization of the Module object. +Module* CreateModule() { + return new MyModule(); +} + +} // namespace pp diff --git a/ppapi/example/example.html b/ppapi/example/example.html new file mode 100644 index 0000000..f6fdc52 --- /dev/null +++ b/ppapi/example/example.html @@ -0,0 +1,17 @@ +<body style="background-image:url(http://www.google.com/intl/en_ALL/images/logo.gif); + background-repeat:repeat"> + +<script type="text/javascript"> +function Test() { + plugin = document.getElementById('plugin'); + // Confirm that this no longer segfaults. + alert(plugin.toString(new Array(10))); +} + +</script> + + <button onclick='Test()'>Test</button> + <div id="fps" style="background-color:white; font-weight:bold; padding:4px;">FPS GOES HERE</div> + <object id="plugin" type="application/x-ppapi-example" width="400" height="400" /> + <hr> +</body> diff --git a/ppapi/example/example.rc b/ppapi/example/example.rc new file mode 100644 index 0000000..9e06702 --- /dev/null +++ b/ppapi/example/example.rc @@ -0,0 +1,30 @@ +1 VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x17L + FILEFLAGS 0x0L + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Google" + VALUE "FileDescription", "Pepper Test Plugin" + VALUE "FileVersion", "1, 0, 0, 1" + VALUE "InternalName", "ppapi_example" + VALUE "LegalCopyright", "Copyright (C) 2010" + VALUE "OriginalFilename", "ppapi_example.dll" + VALUE "ProductName", "Pepper Test Plugin" + VALUE "ProductVersion", "1, 0, 0, 1" + VALUE "MIMEType", "pepper-application/x-pepper-test-plugin" + VALUE "FileExtents", "ptp" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/ppapi/example/example_framed.html b/ppapi/example/example_framed.html new file mode 100644 index 0000000..5247106 --- /dev/null +++ b/ppapi/example/example_framed.html @@ -0,0 +1,2 @@ +<!-- In this invocation of the example plugin, Instance::HandleDocumentLoad is called. --> +<iframe style="width: 90%; height: 90%" src="data:application/x-ppapi-example,hello%20world"></iframe> |