summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-07 23:55:35 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-07 23:55:35 +0000
commite55badb64f610fa03504471ca8edd997a9d3f1b4 (patch)
tree18337beb82a19166cee0166faf9338124d5d6e78 /webkit
parent3d7a219946c1f718357d15cddb954cda5f2c92eb (diff)
downloadchromium_src-e55badb64f610fa03504471ca8edd997a9d3f1b4.zip
chromium_src-e55badb64f610fa03504471ca8edd997a9d3f1b4.tar.gz
chromium_src-e55badb64f610fa03504471ca8edd997a9d3f1b4.tar.bz2
Partially implement the new pepper API in Chrome. This is not actually hooked
up, which will require some changes in render_view as well as the plugin list. TEST=none BUG=none Review URL: http://codereview.chromium.org/1697008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46760 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/glue/plugins/DEPS3
-rw-r--r--webkit/glue/plugins/pepper_device_context_2d.cc200
-rw-r--r--webkit/glue/plugins/pepper_device_context_2d.h58
-rw-r--r--webkit/glue/plugins/pepper_image_data.cc148
-rw-r--r--webkit/glue/plugins/pepper_image_data.h61
-rw-r--r--webkit/glue/plugins/pepper_plugin_delegate.h41
-rw-r--r--webkit/glue/plugins/pepper_plugin_instance.cc231
-rw-r--r--webkit/glue/plugins/pepper_plugin_instance.h80
-rw-r--r--webkit/glue/plugins/pepper_plugin_module.cc206
-rw-r--r--webkit/glue/plugins/pepper_plugin_module.h74
-rw-r--r--webkit/glue/plugins/pepper_resource.cc31
-rw-r--r--webkit/glue/plugins/pepper_resource.h45
-rw-r--r--webkit/glue/plugins/pepper_resource_tracker.cc50
-rw-r--r--webkit/glue/plugins/pepper_resource_tracker.h57
-rw-r--r--webkit/glue/plugins/pepper_string.h30
-rw-r--r--webkit/glue/plugins/pepper_var.cc138
-rw-r--r--webkit/glue/plugins/pepper_var.h19
-rw-r--r--webkit/glue/plugins/pepper_webplugin_delegate_impl.cc160
-rw-r--r--webkit/glue/plugins/pepper_webplugin_delegate_impl.h86
-rw-r--r--webkit/glue/webkit_glue.gypi18
20 files changed, 1736 insertions, 0 deletions
diff --git a/webkit/glue/plugins/DEPS b/webkit/glue/plugins/DEPS
new file mode 100644
index 0000000..21f5108
--- /dev/null
+++ b/webkit/glue/plugins/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+third_party/ppapi/c",
+]
diff --git a/webkit/glue/plugins/pepper_device_context_2d.cc b/webkit/glue/plugins/pepper_device_context_2d.cc
new file mode 100644
index 0000000..3fbc685
--- /dev/null
+++ b/webkit/glue/plugins/pepper_device_context_2d.cc
@@ -0,0 +1,200 @@
+// 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 "webkit/glue/plugins/pepper_device_context_2d.h"
+
+#include "base/logging.h"
+#include "gfx/point.h"
+#include "gfx/rect.h"
+#include "skia/ext/platform_canvas.h"
+#include "third_party/ppapi/c/pp_module.h"
+#include "third_party/ppapi/c/pp_rect.h"
+#include "third_party/ppapi/c/pp_resource.h"
+#include "third_party/ppapi/c/ppb_device_context_2d.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "webkit/glue/plugins/pepper_image_data.h"
+#include "webkit/glue/plugins/pepper_plugin_module.h"
+#include "webkit/glue/plugins/pepper_resource_tracker.h"
+
+#if defined(OS_MACOSX)
+#include "base/mac_util.h"
+#include "base/scoped_cftyperef.h"
+#endif
+
+namespace pepper {
+
+namespace {
+
+PP_Resource Create(PP_Module module_id, int32_t width, int32_t height) {
+ PluginModule* module = PluginModule::FromPPModule(module_id);
+ if (!module)
+ return NullPPResource();
+
+ scoped_refptr<DeviceContext2D> context(new DeviceContext2D(module));
+ if (!context->Init(width, height))
+ return NullPPResource();
+ context->AddRef(); // AddRef for the caller.
+ return context->GetResource();
+}
+
+void PaintImageData(PP_Resource device_context,
+ PP_Resource image,
+ int32_t x, int32_t y,
+ const PP_Rect* dirty,
+ uint32_t dirty_rect_count,
+ PPB_DeviceContext2D_PaintCallback callback,
+ void* callback_data) {
+ scoped_refptr<Resource> device_resource =
+ ResourceTracker::Get()->GetResource(device_context);
+ if (!device_resource.get())
+ return;
+ DeviceContext2D* context = device_resource->AsDeviceContext2D();
+ if (!context)
+ return;
+ context->PaintImageData(image, x, y, dirty, dirty_rect_count,
+ callback, callback_data);
+}
+
+const PPB_DeviceContext2D ppb_devicecontext2d = {
+ &Create,
+ &PaintImageData,
+};
+
+} // namespace
+
+DeviceContext2D::DeviceContext2D(PluginModule* module) : Resource(module) {
+}
+
+DeviceContext2D::~DeviceContext2D() {
+}
+
+// static
+const PPB_DeviceContext2D* DeviceContext2D::GetInterface() {
+ return &ppb_devicecontext2d;
+}
+
+bool DeviceContext2D::Init(int width, int height) {
+ image_data_.reset(new ImageData(module()));
+ if (!image_data_->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, width, height) ||
+ !image_data_->Map()) {
+ image_data_.reset();
+ return false;
+ }
+
+ return true;
+}
+
+void DeviceContext2D::PaintImageData(PP_Resource image,
+ int32_t x, int32_t y,
+ const PP_Rect* dirty,
+ uint32_t dirty_rect_count,
+ PPB_DeviceContext2D_PaintCallback callback,
+ void* callback_data) {
+ scoped_refptr<Resource> image_resource =
+ ResourceTracker::Get()->GetResource(image);
+ if (!image_resource.get())
+ return;
+ ImageData* new_image_data = image_resource->AsImageData();
+ if (!new_image_data)
+ return;
+
+ const SkBitmap& new_image_bitmap = new_image_data->GetMappedBitmap();
+
+ // TODO(brettw) handle multiple dirty rects.
+ DCHECK(dirty_rect_count == 1);
+
+ // Draw the bitmap to the backing store.
+ SkIRect src_rect;
+ if (dirty->left == 0 && dirty->top == 0 &&
+ dirty->right == 0 && dirty->bottom == 0) {
+ // Default to the entire bitmap.
+ src_rect.fLeft = 0;
+ src_rect.fTop = 0;
+ src_rect.fRight = new_image_bitmap.width();
+ src_rect.fBottom = new_image_bitmap.height();
+ } else {
+ src_rect.fLeft = dirty->left;
+ src_rect.fTop = dirty->top;
+ src_rect.fRight = dirty->right;
+ src_rect.fBottom = dirty->bottom;
+ }
+ SkRect dest_rect = { SkIntToScalar(src_rect.fLeft),
+ SkIntToScalar(src_rect.fTop),
+ SkIntToScalar(src_rect.fRight),
+ SkIntToScalar(src_rect.fBottom) };
+
+ // We're guaranteed to have a mapped canvas since we mapped it in Init().
+ skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas();
+
+ // We want to replace the contents of the bitmap rather than blend.
+ SkPaint paint;
+ paint.setXfermodeMode(SkXfermode::kSrc_Mode);
+ backing_canvas->drawBitmapRect(new_image_bitmap,
+ &src_rect, dest_rect, &paint);
+
+ // TODO(brettw) implement invalidate and callbacks!
+
+ // Cause the updated part of the screen to be repainted. This will happen
+ // asynchronously.
+ /*
+ gfx::Rect dest_gfx_rect(dirty->left, dirty->top,
+ dirty->right - dirty->left,
+ dirty->bottom - dirty->top);
+
+ plugin_delegate_->instance()->webplugin()->InvalidateRect(dest_gfx_rect);
+
+ // Save the callback to execute later. See |unpainted_flush_callbacks_| in
+ // the header file.
+ if (callback) {
+ unpainted_flush_callbacks_.push_back(
+ FlushCallbackData(callback, id, context, user_data));
+ }
+*/
+}
+
+void DeviceContext2D::Paint(WebKit::WebCanvas* canvas,
+ const gfx::Rect& plugin_rect,
+ const gfx::Rect& paint_rect) {
+ // We're guaranteed to have a mapped canvas since we mapped it in Init().
+ const SkBitmap& backing_bitmap = image_data_->GetMappedBitmap();
+
+#if defined(OS_MACOSX)
+ SkAutoLockPixels lock(backing_bitmap);
+
+ scoped_cftyperef<CGDataProviderRef> data_provider(
+ CGDataProviderCreateWithData(
+ NULL, backing_bitmap.getAddr32(0, 0),
+ backing_bitmap.rowBytes() * backing_bitmap.height(), NULL));
+ scoped_cftyperef<CGImageRef> image(
+ CGImageCreate(
+ backing_bitmap.width(), backing_bitmap.height(),
+ 8, 32, backing_bitmap.rowBytes(),
+ mac_util::GetSystemColorSpace(),
+ kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
+ data_provider, NULL, false, kCGRenderingIntentDefault));
+
+ // Flip the transform
+ CGContextSaveGState(canvas);
+ float window_height = static_cast<float>(CGBitmapContextGetHeight(canvas));
+ CGContextTranslateCTM(canvas, 0, window_height);
+ CGContextScaleCTM(canvas, 1.0, -1.0);
+
+ CGRect bounds;
+ bounds.origin.x = plugin_rect.origin().x();
+ bounds.origin.y = window_height - plugin_rect.origin().y() -
+ backing_bitmap.height();
+ bounds.size.width = backing_bitmap.width();
+ bounds.size.height = backing_bitmap.height();
+
+ CGContextDrawImage(canvas, bounds, image);
+ CGContextRestoreGState(canvas);
+#else
+ gfx::Point origin(plugin_rect.origin().x(), plugin_rect.origin().y());
+ canvas->drawBitmap(backing_bitmap,
+ SkIntToScalar(plugin_rect.origin().x()),
+ SkIntToScalar(plugin_rect.origin().y()));
+#endif
+}
+
+} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_device_context_2d.h b/webkit/glue/plugins/pepper_device_context_2d.h
new file mode 100644
index 0000000..8f40692
--- /dev/null
+++ b/webkit/glue/plugins/pepper_device_context_2d.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 WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_2D_H_
+#define WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_2D_H_
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "third_party/ppapi/c/ppb_device_context_2d.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebCanvas.h"
+#include "webkit/glue/plugins/pepper_resource.h"
+
+typedef struct _ppb_DeviceContext2D PPB_DeviceContext2D;
+
+namespace gfx {
+class Rect;
+}
+
+namespace pepper {
+
+class ImageData;
+class PluginModule;
+
+class DeviceContext2D : public Resource {
+ public:
+ DeviceContext2D(PluginModule* module);
+ virtual ~DeviceContext2D();
+
+ // Returns a pointer to the interface implementing PPB_ImageData that is
+ // exposed to the plugin.
+ static const PPB_DeviceContext2D* GetInterface();
+
+ bool Init(int width, int height);
+
+ // Resource override.
+ virtual DeviceContext2D* AsDeviceContext2D() { return this; }
+
+ void PaintImageData(PP_Resource image,
+ int32_t x, int32_t y,
+ const PP_Rect* dirty,
+ uint32_t dirty_rect_count,
+ PPB_DeviceContext2D_PaintCallback callback,
+ void* callback_data);
+
+ void Paint(WebKit::WebCanvas* canvas,
+ const gfx::Rect& plugin_rect,
+ const gfx::Rect& paint_rect);
+
+ private:
+ scoped_ptr<ImageData> image_data_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeviceContext2D);
+};
+
+} // namespace pepper
+
+#endif // WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_2D_H_
diff --git a/webkit/glue/plugins/pepper_image_data.cc b/webkit/glue/plugins/pepper_image_data.cc
new file mode 100644
index 0000000..c53c91b
--- /dev/null
+++ b/webkit/glue/plugins/pepper_image_data.cc
@@ -0,0 +1,148 @@
+// 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 "webkit/glue/plugins/pepper_image_data.h"
+
+#include "base/scoped_ptr.h"
+#include "skia/ext/platform_canvas.h"
+#include "third_party/ppapi/c/pp_instance.h"
+#include "third_party/ppapi/c/pp_module.h"
+#include "third_party/ppapi/c/pp_resource.h"
+#include "third_party/ppapi/c/ppb_image_data.h"
+#include "webkit/glue/plugins/pepper_plugin_instance.h"
+#include "webkit/glue/plugins/pepper_plugin_module.h"
+#include "webkit/glue/plugins/pepper_resource_tracker.h"
+
+namespace pepper {
+
+namespace {
+
+ImageData* ResourceAsImageData(PP_Resource resource) {
+ scoped_refptr<Resource> image_resource =
+ ResourceTracker::Get()->GetResource(resource);
+ if (!image_resource.get())
+ return NULL;
+ return image_resource->AsImageData();
+}
+
+PP_Resource Create(PP_Module module_id,
+ PP_ImageDataFormat format,
+ int32_t width,
+ int32_t height) {
+ PluginModule* module = PluginModule::FromPPModule(module_id);
+ if (!module)
+ return NullPPResource();
+
+ scoped_refptr<ImageData> data(new ImageData(module));
+ if (!data->Init(format, width, height))
+ return NullPPResource();
+ data->AddRef(); // AddRef for the caller.
+
+ return data->GetResource();
+}
+
+bool IsImageData(PP_Resource resource) {
+ scoped_refptr<Resource> image_resource =
+ ResourceTracker::Get()->GetResource(resource);
+ if (!image_resource.get())
+ return false;
+ return !!image_resource->AsImageData();
+}
+
+bool Describe(PP_Resource resource,
+ PP_ImageDataDesc* desc) {
+ // Give predictable values on failure.
+ memset(desc, 0, sizeof(PP_ImageDataDesc));
+
+ ImageData* image_data = ResourceAsImageData(resource);
+ if (!image_data)
+ return false;
+ image_data->Describe(desc);
+ return true;
+}
+
+void* Map(PP_Resource resource) {
+ ImageData* image_data = ResourceAsImageData(resource);
+ if (!image_data)
+ return NULL;
+ return image_data->Map();
+}
+
+void Unmap(PP_Resource resource) {
+ ImageData* image_data = ResourceAsImageData(resource);
+ if (!image_data)
+ return;
+ return image_data->Unmap();
+}
+
+const PPB_ImageData ppb_imagedata = {
+ &Create,
+ &IsImageData,
+ &Describe,
+ &Map,
+ &Unmap,
+};
+
+} // namespace
+
+ImageData::ImageData(PluginModule* module)
+ : Resource(module),
+ width_(0),
+ height_(0) {
+}
+
+ImageData::~ImageData() {
+}
+
+// static
+const PPB_ImageData* ImageData::GetInterface() {
+ return &ppb_imagedata;
+}
+
+bool ImageData::Init(PP_ImageDataFormat format,
+ int width,
+ int height) {
+ // TODO(brettw) this should be called only on the main thread!
+ platform_image_.reset(
+ module()->GetSomeInstance()->delegate()->CreateImage2D(width, height));
+ width_ = width;
+ height_ = height;
+ return !!platform_image_.get();
+}
+
+void ImageData::Describe(PP_ImageDataDesc* desc) const {
+ desc->format = PP_IMAGEDATAFORMAT_BGRA_PREMUL;
+ desc->width = width_;
+ desc->height = height_;
+ desc->stride = width_ * 4;
+}
+
+void* ImageData::Map() {
+ if (!mapped_canvas_.get()) {
+ mapped_canvas_.reset(platform_image_->Map());
+ if (!mapped_canvas_.get())
+ return NULL;
+ }
+ const SkBitmap& bitmap =
+ mapped_canvas_->getTopPlatformDevice().accessBitmap(true);
+
+ // Our platform bitmaps are set to opaque by default, which we don't want.
+ const_cast<SkBitmap&>(bitmap).setIsOpaque(false);
+
+ bitmap.lockPixels();
+ return bitmap.getAddr32(0, 0);
+}
+
+void ImageData::Unmap() {
+ // This is currently unimplemented, which is OK. The data will just always
+ // be around once it's mapped. Chrome's TransportDIB isn't currently
+ // unmappable without freeing it, but this may be something we want to support
+ // in the future to save some memory.
+}
+
+const SkBitmap& ImageData::GetMappedBitmap() const {
+ return mapped_canvas_->getTopPlatformDevice().accessBitmap(false);
+}
+
+} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_image_data.h b/webkit/glue/plugins/pepper_image_data.h
new file mode 100644
index 0000000..e4af427
--- /dev/null
+++ b/webkit/glue/plugins/pepper_image_data.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 WEBKIT_GLUE_PLUGINS_PEPPER_IMAGE_DATA_H_
+#define WEBKIT_GLUE_PLUGINS_PEPPER_IMAGE_DATA_H_
+
+#include "base/scoped_ptr.h"
+#include "third_party/ppapi/c/ppb_image_data.h"
+#include "webkit/glue/plugins/pepper_plugin_delegate.h"
+#include "webkit/glue/plugins/pepper_resource.h"
+
+typedef struct _ppb_ImageData PPB_ImageData;
+
+namespace skia {
+class PlatformCanvas;
+}
+
+class SkBitmap;
+
+namespace pepper {
+
+class PluginInstance;
+
+class ImageData : public Resource {
+ public:
+ explicit ImageData(PluginModule* module);
+ virtual ~ImageData();
+
+ // Returns a pointer to the interface implementing PPB_ImageData that is
+ // exposed to the plugin.
+ static const PPB_ImageData* GetInterface();
+
+ // Resource overrides.
+ ImageData* AsImageData() { return this; }
+
+ // PPB_ImageData implementation.
+ bool Init(PP_ImageDataFormat format,
+ int width,
+ int height);
+ void Describe(PP_ImageDataDesc* desc) const;
+ void* Map();
+ void Unmap();
+
+ skia::PlatformCanvas* mapped_canvas() const { return mapped_canvas_.get(); }
+
+ const SkBitmap& GetMappedBitmap() const;
+
+ private:
+ scoped_ptr<PluginDelegate::PlatformImage2D> platform_image_;
+
+ // When the device is mapped, this is the image. Null when umapped.
+ scoped_ptr<skia::PlatformCanvas> mapped_canvas_;
+
+ int width_;
+ int height_;
+};
+
+} // namespace pepper
+
+#endif // WEBKIT_GLUE_PLUGINS_PEPPER_IMAGE_DATA_H_
diff --git a/webkit/glue/plugins/pepper_plugin_delegate.h b/webkit/glue/plugins/pepper_plugin_delegate.h
new file mode 100644
index 0000000..9515b17
--- /dev/null
+++ b/webkit/glue/plugins/pepper_plugin_delegate.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 WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_DELEGATE_H_
+#define WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_DELEGATE_H_
+
+#include "third_party/ppapi/c/pp_stdint.h"
+
+namespace skia {
+class PlatformCanvas;
+}
+
+namespace pepper {
+
+// Virtual interface that the browser implements to implement features for
+// Pepper plugins.
+class PluginDelegate {
+ public:
+ // Represents an image. This is to allow the browser layer to supply a correct
+ // image representation. In Chrome, this will be a TransportDIB.
+ class PlatformImage2D {
+ public:
+ virtual ~PlatformImage2D() {}
+
+ // Caller will own the returned pointer, returns NULL on failure.
+ virtual skia::PlatformCanvas* Map() = 0;
+
+ // Returns the platform-specific shared memory handle of the data backing
+ // this image. This is used by NativeClient to send the image to the
+ // out-of-process plugin. Returns 0 on failure.
+ virtual intptr_t GetSharedMemoryHandle() const = 0;
+ };
+
+ // The caller will own the pointer returned from this.
+ virtual PlatformImage2D* CreateImage2D(int width, int height) = 0;
+};
+
+} // namespace pepper
+
+#endif // WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_DELEGATE_H_
diff --git a/webkit/glue/plugins/pepper_plugin_instance.cc b/webkit/glue/plugins/pepper_plugin_instance.cc
new file mode 100644
index 0000000..17edef3
--- /dev/null
+++ b/webkit/glue/plugins/pepper_plugin_instance.cc
@@ -0,0 +1,231 @@
+// 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 "webkit/glue/plugins/pepper_plugin_instance.h"
+
+#include "base/logging.h"
+#include "base/scoped_ptr.h"
+#include "gfx/rect.h"
+#include "third_party/ppapi/c/pp_instance.h"
+#include "third_party/ppapi/c/pp_event.h"
+#include "third_party/ppapi/c/pp_rect.h"
+#include "third_party/ppapi/c/pp_resource.h"
+#include "third_party/ppapi/c/ppb_instance.h"
+#include "third_party/ppapi/c/ppp_instance.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
+#include "webkit/glue/plugins/pepper_device_context_2d.h"
+#include "webkit/glue/plugins/pepper_plugin_module.h"
+#include "webkit/glue/plugins/pepper_resource_tracker.h"
+
+using WebKit::WebInputEvent;
+
+namespace pepper {
+
+namespace {
+
+void RectToPPRect(const gfx::Rect& input, PP_Rect* output) {
+ output->left = input.x();
+ output->top = input.y();
+ output->right = input.right();
+ output->bottom = input.bottom();
+}
+
+PP_Event_Type ConvertEventTypes(WebInputEvent::Type wetype) {
+ switch (wetype) {
+ case WebInputEvent::MouseDown:
+ return PP_Event_Type_MouseDown;
+ case WebInputEvent::MouseUp:
+ return PP_Event_Type_MouseUp;
+ case WebInputEvent::MouseMove:
+ return PP_Event_Type_MouseMove;
+ case WebInputEvent::MouseEnter:
+ return PP_Event_Type_MouseEnter;
+ case WebInputEvent::MouseLeave:
+ return PP_Event_Type_MouseLeave;
+ case WebInputEvent::MouseWheel:
+ return PP_Event_Type_MouseWheel;
+ case WebInputEvent::RawKeyDown:
+ return PP_Event_Type_RawKeyDown;
+ case WebInputEvent::KeyDown:
+ return PP_Event_Type_KeyDown;
+ case WebInputEvent::KeyUp:
+ return PP_Event_Type_KeyUp;
+ case WebInputEvent::Char:
+ return PP_Event_Type_Char;
+ case WebInputEvent::Undefined:
+ default:
+ return PP_Event_Type_Undefined;
+ }
+}
+
+void BuildKeyEvent(const WebInputEvent* event, PP_Event* pp_event) {
+ const WebKit::WebKeyboardEvent* key_event =
+ reinterpret_cast<const WebKit::WebKeyboardEvent*>(event);
+ pp_event->u.key.modifier = key_event->modifiers;
+ pp_event->u.key.normalizedKeyCode = key_event->windowsKeyCode;
+}
+
+void BuildCharEvent(const WebInputEvent* event, PP_Event* pp_event) {
+ const WebKit::WebKeyboardEvent* key_event =
+ reinterpret_cast<const WebKit::WebKeyboardEvent*>(event);
+ pp_event->u.character.modifier = key_event->modifiers;
+ // For consistency, check that the sizes of the texts agree.
+ DCHECK(sizeof(pp_event->u.character.text) == sizeof(key_event->text));
+ DCHECK(sizeof(pp_event->u.character.unmodifiedText) ==
+ sizeof(key_event->unmodifiedText));
+ for (size_t i = 0; i < WebKit::WebKeyboardEvent::textLengthCap; ++i) {
+ pp_event->u.character.text[i] = key_event->text[i];
+ pp_event->u.character.unmodifiedText[i] = key_event->unmodifiedText[i];
+ }
+}
+
+void BuildMouseEvent(const WebInputEvent* event, PP_Event* pp_event) {
+ const WebKit::WebMouseEvent* mouse_event =
+ reinterpret_cast<const WebKit::WebMouseEvent*>(event);
+ pp_event->u.mouse.modifier = mouse_event->modifiers;
+ pp_event->u.mouse.button = mouse_event->button;
+ pp_event->u.mouse.x = mouse_event->x;
+ pp_event->u.mouse.y = mouse_event->y;
+ pp_event->u.mouse.clickCount = mouse_event->clickCount;
+}
+
+void BuildMouseWheelEvent(const WebInputEvent* event, PP_Event* pp_event) {
+ const WebKit::WebMouseWheelEvent* mouse_wheel_event =
+ reinterpret_cast<const WebKit::WebMouseWheelEvent*>(event);
+ pp_event->u.wheel.modifier = mouse_wheel_event->modifiers;
+ pp_event->u.wheel.deltaX = mouse_wheel_event->deltaX;
+ pp_event->u.wheel.deltaY = mouse_wheel_event->deltaY;
+ pp_event->u.wheel.wheelTicksX = mouse_wheel_event->wheelTicksX;
+ pp_event->u.wheel.wheelTicksY = mouse_wheel_event->wheelTicksY;
+ pp_event->u.wheel.scrollByPage = mouse_wheel_event->scrollByPage;
+}
+
+bool BindGraphicsDeviceContext(PP_Instance instance_id, PP_Resource device_id) {
+ PluginInstance* instance = PluginInstance::FromPPInstance(instance_id);
+ if (!instance)
+ return false;
+ return instance->BindGraphicsDeviceContext(device_id);
+}
+
+const PPB_Instance ppb_instance = {
+ &BindGraphicsDeviceContext,
+};
+
+} // namespace
+
+PluginInstance::PluginInstance(PluginDelegate* delegate,
+ PluginModule* module,
+ const PPP_Instance* instance_interface)
+ : delegate_(delegate),
+ module_(module),
+ instance_interface_(instance_interface) {
+ DCHECK(delegate);
+ module_->InstanceCreated(this);
+}
+
+PluginInstance::~PluginInstance() {
+ module_->InstanceDeleted(this);
+}
+
+// static
+const PPB_Instance* PluginInstance::GetInterface() {
+ return &ppb_instance;
+}
+
+// static
+PluginInstance* PluginInstance::FromPPInstance(PP_Instance instance) {
+ return reinterpret_cast<PluginInstance*>(instance.id);
+}
+
+PP_Instance PluginInstance::GetPPInstance() {
+ PP_Instance ret;
+ ret.id = reinterpret_cast<intptr_t>(this);
+ return ret;
+}
+
+void PluginInstance::Paint(WebKit::WebCanvas* canvas,
+ const gfx::Rect& plugin_rect,
+ const gfx::Rect& paint_rect) {
+ if (device_context_2d_)
+ device_context_2d_->Paint(canvas, plugin_rect, paint_rect);
+}
+
+bool PluginInstance::BindGraphicsDeviceContext(PP_Resource device_id) {
+ scoped_refptr<Resource> device_resource =
+ ResourceTracker::Get()->GetResource(device_id);
+ if (!device_resource.get())
+ return false;
+
+ DeviceContext2D* device_2d = device_resource->AsDeviceContext2D();
+ if (device_2d) {
+ device_context_2d_ = device_2d;
+ // TODO(brettw) repaint the plugin.
+ }
+
+ return true;
+}
+
+void PluginInstance::Delete() {
+ instance_interface_->Delete(GetPPInstance());
+}
+
+bool PluginInstance::Initialize(const std::vector<std::string>& arg_names,
+ const std::vector<std::string>& arg_values) {
+ if (!instance_interface_->New(GetPPInstance()))
+ return false;
+
+ size_t argc = 0;
+ scoped_array<const char*> argn(new const char*[arg_names.size()]);
+ scoped_array<const char*> argv(new const char*[arg_names.size()]);
+ for (size_t i = 0; i < arg_names.size(); ++i) {
+ argn[argc] = arg_names[i].c_str();
+ argv[argc] = arg_values[i].c_str();
+ argc++;
+ }
+
+ return instance_interface_->Initialize(GetPPInstance(),
+ argc, argn.get(), argv.get());
+}
+
+bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event,
+ WebKit::WebCursorInfo* cursor_info) {
+ PP_Event pp_event;
+
+ pp_event.type = ConvertEventTypes(event.type);
+ pp_event.size = sizeof(pp_event);
+ pp_event.time_stamp_seconds = event.timeStampSeconds;
+ switch (pp_event.type) {
+ case PP_Event_Type_Undefined:
+ return false;
+ case PP_Event_Type_MouseDown:
+ case PP_Event_Type_MouseUp:
+ case PP_Event_Type_MouseMove:
+ case PP_Event_Type_MouseEnter:
+ case PP_Event_Type_MouseLeave:
+ BuildMouseEvent(&event, &pp_event);
+ break;
+ case PP_Event_Type_MouseWheel:
+ BuildMouseWheelEvent(&event, &pp_event);
+ break;
+ case PP_Event_Type_RawKeyDown:
+ case PP_Event_Type_KeyDown:
+ case PP_Event_Type_KeyUp:
+ BuildKeyEvent(&event, &pp_event);
+ break;
+ case PP_Event_Type_Char:
+ BuildCharEvent(&event, &pp_event);
+ break;
+ }
+ return instance_interface_->HandleEvent(GetPPInstance(), &pp_event);
+}
+
+void PluginInstance::ViewChanged(const gfx::Rect& position,
+ const gfx::Rect& clip) {
+ PP_Rect pp_position, pp_clip;
+ RectToPPRect(position, &pp_position);
+ RectToPPRect(clip, &pp_clip);
+ instance_interface_->ViewChanged(GetPPInstance(), &pp_position, &pp_clip);
+}
+
+} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_plugin_instance.h b/webkit/glue/plugins/pepper_plugin_instance.h
new file mode 100644
index 0000000..3ff3212
--- /dev/null
+++ b/webkit/glue/plugins/pepper_plugin_instance.h
@@ -0,0 +1,80 @@
+// 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 WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_INSTANCE_H_
+#define WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_INSTANCE_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebCanvas.h"
+
+typedef struct _pp_Instance PP_Instance;
+typedef struct _pp_Resource PP_Resource;
+typedef struct _ppb_Instance PPB_Instance;
+typedef struct _ppp_Instance PPP_Instance;
+
+namespace gfx {
+class Rect;
+}
+
+namespace WebKit {
+struct WebCursorInfo;
+class WebInputEvent;
+}
+
+namespace pepper {
+
+class DeviceContext2D;
+class PluginDelegate;
+class PluginModule;
+
+class PluginInstance : public base::RefCounted<PluginInstance> {
+ public:
+ PluginInstance(PluginDelegate* delegate,
+ PluginModule* module,
+ const PPP_Instance* instance_interface);
+ ~PluginInstance();
+
+ static const PPB_Instance* GetInterface();
+
+ // Converts the given instance ID to an actual instance object.
+ static PluginInstance* FromPPInstance(PP_Instance instance);
+
+ PluginDelegate* delegate() const { return delegate_; }
+ PluginModule* module() const { return module_.get(); }
+
+ PP_Instance GetPPInstance();
+
+ void Paint(WebKit::WebCanvas* canvas,
+ const gfx::Rect& plugin_rect,
+ const gfx::Rect& paint_rect);
+
+ // PPB_Instance implementation.
+ bool BindGraphicsDeviceContext(PP_Resource device_id);
+
+ // PPP_Instance pass-through.
+ void Delete();
+ bool Initialize(const std::vector<std::string>& arg_names,
+ const std::vector<std::string>& arg_values);
+ bool HandleInputEvent(const WebKit::WebInputEvent& event,
+ WebKit::WebCursorInfo* cursor_info);
+ void ViewChanged(const gfx::Rect& position, const gfx::Rect& clip);
+
+ private:
+ PluginDelegate* delegate_;
+ scoped_refptr<PluginModule> module_;
+ const PPP_Instance* instance_interface_;
+
+ // The current device context for painting in 2D.
+ scoped_refptr<DeviceContext2D> device_context_2d_;
+
+ DISALLOW_COPY_AND_ASSIGN(PluginInstance);
+};
+
+} // namespace pepper
+
+#endif // WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_INSTANCE_H_
diff --git a/webkit/glue/plugins/pepper_plugin_module.cc b/webkit/glue/plugins/pepper_plugin_module.cc
new file mode 100644
index 0000000..3eac61e
--- /dev/null
+++ b/webkit/glue/plugins/pepper_plugin_module.cc
@@ -0,0 +1,206 @@
+// 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 "webkit/glue/plugins/pepper_plugin_module.h"
+
+#include <set>
+
+#include "base/logging.h"
+#include "base/scoped_ptr.h"
+#include "third_party/ppapi/c/ppb_core.h"
+#include "third_party/ppapi/c/ppb_device_context_2d.h"
+#include "third_party/ppapi/c/ppb_image_data.h"
+#include "third_party/ppapi/c/ppb_instance.h"
+#include "third_party/ppapi/c/ppb_var.h"
+#include "third_party/ppapi/c/ppp.h"
+#include "third_party/ppapi/c/ppp_instance.h"
+#include "third_party/ppapi/c/pp_module.h"
+#include "third_party/ppapi/c/pp_resource.h"
+#include "third_party/ppapi/c/pp_var.h"
+#include "webkit/glue/plugins/pepper_device_context_2d.h"
+#include "webkit/glue/plugins/pepper_image_data.h"
+#include "webkit/glue/plugins/pepper_plugin_instance.h"
+#include "webkit/glue/plugins/pepper_resource_tracker.h"
+#include "webkit/glue/plugins/pepper_var.h"
+
+typedef bool (*PPP_InitializeModuleFunc)(PP_Module, PPB_GetInterface);
+typedef void (*PPP_ShutdownModuleFunc)();
+
+namespace pepper {
+
+namespace {
+
+// Maintains all currently loaded plugin libs for validating PP_Module
+// identifiers.
+typedef std::set<PluginModule*> PluginModuleSet;
+
+PluginModuleSet* GetLivePluginSet() {
+ static PluginModuleSet live_plugin_libs;
+ return &live_plugin_libs;
+}
+
+// PPB_Core --------------------------------------------------------------------
+
+void AddRefResource(PP_Resource resource) {
+ Resource* res = ResourceTracker::Get()->GetResource(resource);
+ if (!res) {
+ DLOG(WARNING) << "AddRef()ing a nonexistent resource";
+ return;
+ }
+ res->AddRef();
+}
+
+void ReleaseResource(PP_Resource resource) {
+ Resource* res = ResourceTracker::Get()->GetResource(resource);
+ if (!res) {
+ DLOG(WARNING) << "Release()ing a nonexistent resource";
+ return;
+ }
+ res->Release();
+}
+
+const PPB_Core core_interface = {
+ &AddRefResource,
+ &ReleaseResource,
+};
+
+// GetInterface ----------------------------------------------------------------
+
+const void* GetInterface(const char* name) {
+ if (strcmp(name, PPB_CORE_INTERFACE) == 0)
+ return &core_interface;
+ if (strcmp(name, PPB_VAR_INTERFACE) == 0)
+ return GetVarInterface();
+ if (strcmp(name, PPB_INSTANCE_INTERFACE) == 0)
+ return PluginInstance::GetInterface();
+ if (strcmp(name, PPB_IMAGEDATA_INTERFACE) == 0)
+ return ImageData::GetInterface();
+ if (strcmp(name, PPB_DEVICECONTEXT2D_INTERFACE) == 0)
+ return DeviceContext2D::GetInterface();
+ return NULL;
+}
+
+} // namespace
+
+PluginModule::PluginModule(const FilePath& filename)
+ : filename_(filename),
+ initialized_(false),
+ library_(0),
+ ppp_get_interface_(NULL) {
+ GetLivePluginSet()->insert(this);
+}
+
+PluginModule::~PluginModule() {
+ // When the module is being deleted, there should be no more instances still
+ // holding a reference to us.
+ DCHECK(instances_.empty());
+
+ GetLivePluginSet()->erase(this);
+
+ if (library_) {
+ PPP_ShutdownModuleFunc shutdown_module =
+ reinterpret_cast<PPP_ShutdownModuleFunc>(
+ base::GetFunctionPointerFromNativeLibrary(library_,
+ "PPP_ShutdownModule"));
+ if (shutdown_module)
+ shutdown_module();
+ base::UnloadNativeLibrary(library_);
+ }
+}
+
+// static
+scoped_refptr<PluginModule> PluginModule::CreateModule(
+ const FilePath& filename) {
+ // FIXME(brettw) do uniquifying of the plugin here like the NPAPI one.
+
+ scoped_refptr<PluginModule> lib(new PluginModule(filename));
+ if (!lib->Load())
+ lib = NULL;
+ return lib;
+}
+
+// static
+PluginModule* PluginModule::FromPPModule(PP_Module module) {
+ PluginModule* lib = reinterpret_cast<PluginModule*>(module.id);
+ if (GetLivePluginSet()->find(lib) == GetLivePluginSet()->end())
+ return NULL; // Invalid plugin.
+ return lib;
+}
+
+bool PluginModule::Load() {
+ if (initialized_)
+ return true;
+ initialized_ = true;
+
+ library_ = base::LoadNativeLibrary(filename_);
+ if (!library_)
+ return false;
+
+ // Save the GetInterface function pointer for later.
+ ppp_get_interface_ =
+ reinterpret_cast<PPP_GetInterfaceFunc>(
+ base::GetFunctionPointerFromNativeLibrary(library_,
+ "PPP_GetInterface"));
+ if (!ppp_get_interface_) {
+ LOG(WARNING) << "No PPP_GetInterface in plugin library";
+ return false;
+ }
+
+ // Call the plugin initialize function.
+ PPP_InitializeModuleFunc initialize_module =
+ reinterpret_cast<PPP_InitializeModuleFunc>(
+ base::GetFunctionPointerFromNativeLibrary(library_,
+ "PPP_InitializeModule"));
+ if (!initialize_module) {
+ LOG(WARNING) << "No PPP_InitializeModule in plugin library";
+ return false;
+ }
+ int retval = initialize_module(GetPPModule(), &GetInterface);
+ if (retval != 0) {
+ LOG(WARNING) << "PPP_InitializeModule returned failure " << retval;
+ return false;
+ }
+
+ return true;
+}
+
+PP_Module PluginModule::GetPPModule() const {
+ PP_Module ret;
+ ret.id = reinterpret_cast<intptr_t>(this);
+ return ret;
+}
+
+PluginInstance* PluginModule::CreateInstance(PluginDelegate* delegate) {
+ const PPP_Instance* plugin_instance_interface =
+ reinterpret_cast<const PPP_Instance*>(GetPluginInterface(
+ PPP_INSTANCE_INTERFACE));
+ if (!plugin_instance_interface) {
+ LOG(WARNING) << "Plugin doesn't support instance interface, failing.";
+ return NULL;
+ }
+ return new PluginInstance(delegate, this, plugin_instance_interface);
+}
+
+PluginInstance* PluginModule::GetSomeInstance() const {
+ // This will generally crash later if there is not actually any instance to
+ // return, so we force a crash now to make bugs easier to track down.
+ CHECK(!instances_.empty());
+ return *instances_.begin();
+}
+
+const void* PluginModule::GetPluginInterface(const char* name) const {
+ if (!ppp_get_interface_)
+ return NULL;
+ return ppp_get_interface_(name);
+}
+
+void PluginModule::InstanceCreated(PluginInstance* instance) {
+ instances_.insert(instance);
+}
+
+void PluginModule::InstanceDeleted(PluginInstance* instance) {
+ instances_.erase(instance);
+}
+
+} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_plugin_module.h b/webkit/glue/plugins/pepper_plugin_module.h
new file mode 100644
index 0000000..d14b641
--- /dev/null
+++ b/webkit/glue/plugins/pepper_plugin_module.h
@@ -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.
+
+#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_MODULE_H_
+#define WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_MODULE_H_
+
+#include <set>
+
+#include "base/basictypes.h"
+#include "base/file_path.h"
+#include "base/native_library.h"
+#include "base/ref_counted.h"
+
+typedef struct _pp_Module PP_Module;
+
+namespace pepper {
+
+class PluginDelegate;
+class PluginInstance;
+
+class PluginModule : public base::RefCounted<PluginModule> {
+ public:
+ ~PluginModule();
+
+ static scoped_refptr<PluginModule> CreateModule(const FilePath& filename);
+
+ // Converts the given module ID to an actual module object. Will return NULL
+ // if the module is invalid.
+ static PluginModule* FromPPModule(PP_Module module);
+
+ PP_Module GetPPModule() const;
+
+ PluginInstance* CreateInstance(PluginDelegate* delegate);
+
+ // Returns "some" plugin instance associated with this module. This is not
+ // guaranteed to be any one in particular. This is normally used to execute
+ // callbacks up to the browser layer that are not inherently per-instance,
+ // but the delegate lives only on the plugin instance so we need one of them.
+ PluginInstance* GetSomeInstance() const;
+
+ const void* GetPluginInterface(const char* name) const;
+
+ // This module is associated with a set of instances. The PluginInstance
+ // object declares its association with this module in its destructor and
+ // releases us in its destructor.
+ void InstanceCreated(PluginInstance* instance);
+ void InstanceDeleted(PluginInstance* instance);
+
+ private:
+ typedef const void* (*PPP_GetInterfaceFunc)(const char*);
+
+ explicit PluginModule(const FilePath& filename);
+
+ bool Load();
+
+ FilePath filename_;
+
+ bool initialized_;
+ base::NativeLibrary library_;
+
+ PPP_GetInterfaceFunc ppp_get_interface_;
+
+ // Non-owning pointers to all instances associated with this module. When
+ // there are no more instances, this object should be deleted.
+ typedef std::set<PluginInstance*> PluginInstanceSet;
+ PluginInstanceSet instances_;
+
+ DISALLOW_COPY_AND_ASSIGN(PluginModule);
+};
+
+} // namespace pepper
+
+#endif // WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_MODULE_H_
diff --git a/webkit/glue/plugins/pepper_resource.cc b/webkit/glue/plugins/pepper_resource.cc
new file mode 100644
index 0000000..d7ed281
--- /dev/null
+++ b/webkit/glue/plugins/pepper_resource.cc
@@ -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.
+
+#include "webkit/glue/plugins/pepper_resource.h"
+
+#include "third_party/ppapi/c/pp_resource.h"
+#include "webkit/glue/plugins/pepper_resource_tracker.h"
+
+namespace pepper {
+
+PP_Resource NullPPResource() {
+ PP_Resource ret = { 0 };
+ return ret;
+}
+
+Resource::Resource(PluginModule* module) : module_(module) {
+ ResourceTracker::Get()->AddResource(this);
+}
+
+Resource::~Resource() {
+ ResourceTracker::Get()->DeleteResource(this);
+}
+
+PP_Resource Resource::GetResource() const {
+ PP_Resource ret;
+ ret.id = reinterpret_cast<intptr_t>(this);
+ return ret;
+}
+
+} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_resource.h b/webkit/glue/plugins/pepper_resource.h
new file mode 100644
index 0000000..6cf1e28
--- /dev/null
+++ b/webkit/glue/plugins/pepper_resource.h
@@ -0,0 +1,45 @@
+// 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 WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_H_
+#define WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_H_
+
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+
+typedef struct _pp_Resource PP_Resource;
+
+namespace pepper {
+
+class DeviceContext2D;
+class ImageData;
+class PluginModule;
+
+class Resource : public base::RefCountedThreadSafe<Resource> {
+ public:
+ explicit Resource(PluginModule* module);
+ virtual ~Resource();
+
+ PP_Resource GetResource() const;
+
+ PluginModule* module() const { return module_; }
+
+ // Type-specific getters for individual resource types. These will return
+ // NULL if the resource does not match the specified type.
+ virtual DeviceContext2D* AsDeviceContext2D() { return NULL; }
+ virtual ImageData* AsImageData() { return NULL; }
+
+ private:
+ PluginModule* module_; // Non-owning pointer to our module.
+
+ DISALLOW_COPY_AND_ASSIGN(Resource);
+};
+
+// Returns a "NULL" resource. This is just a helper function so callers
+// can avoid creating a resource with a 0 ID.
+PP_Resource NullPPResource();
+
+} // namespace pepper
+
+#endif // WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_H_
diff --git a/webkit/glue/plugins/pepper_resource_tracker.cc b/webkit/glue/plugins/pepper_resource_tracker.cc
new file mode 100644
index 0000000..13c5c2c
--- /dev/null
+++ b/webkit/glue/plugins/pepper_resource_tracker.cc
@@ -0,0 +1,50 @@
+// 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 "webkit/glue/plugins/pepper_resource_tracker.h"
+
+#include <set>
+
+#include "base/logging.h"
+#include "third_party/ppapi/c/pp_resource.h"
+#include "webkit/glue/plugins/pepper_resource.h"
+
+namespace pepper {
+
+ResourceTracker::ResourceTracker() {
+}
+
+ResourceTracker::~ResourceTracker() {
+}
+
+// static
+ResourceTracker* ResourceTracker::Get() {
+ return Singleton<ResourceTracker>::get();
+}
+
+Resource* ResourceTracker::GetResource(PP_Resource res) const {
+ AutoLock lock(lock_);
+ Resource* resource = reinterpret_cast<Resource*>(res.id);
+ if (live_resources_.find(resource) == live_resources_.end())
+ return NULL;
+ return resource;
+}
+
+void ResourceTracker::AddResource(Resource* resource) {
+ AutoLock lock(lock_);
+ DCHECK(live_resources_.find(resource) == live_resources_.end());
+ live_resources_.insert(resource);
+}
+
+void ResourceTracker::DeleteResource(Resource* resource) {
+ AutoLock lock(lock_);
+ ResourceSet::iterator found = live_resources_.find(resource);
+ if (found == live_resources_.end()) {
+ NOTREACHED();
+ return;
+ }
+ live_resources_.erase(found);
+}
+
+} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_resource_tracker.h b/webkit/glue/plugins/pepper_resource_tracker.h
new file mode 100644
index 0000000..f114549
--- /dev/null
+++ b/webkit/glue/plugins/pepper_resource_tracker.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 WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_TRACKER_H_
+#define WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_TRACKER_H_
+
+#include <set>
+
+#include "base/atomic_sequence_num.h"
+#include "base/basictypes.h"
+#include "base/lock.h"
+#include "base/ref_counted.h"
+#include "base/singleton.h"
+
+typedef struct _pp_Resource PP_Resource;
+
+namespace pepper {
+
+class Resource;
+
+// This class maintains a global list of all live pepper resources. It allows
+// us to check resource ID validity and to map them to a specific module.
+//
+// This object is threadsafe.
+class ResourceTracker {
+ public:
+ // Returns the pointer to the singleton object.
+ static ResourceTracker* Get();
+
+ // The returned pointer will be NULL if there is no resource.
+ Resource* GetResource(PP_Resource res) const;
+
+ // Adds the given resource to the tracker and assigns it a resource ID. The
+ // assigned resource ID will be returned.
+ void AddResource(Resource* resource);
+
+ void DeleteResource(Resource* resource);
+
+ private:
+ friend struct DefaultSingletonTraits<ResourceTracker>;
+
+ ResourceTracker();
+ ~ResourceTracker();
+
+ // Hold this lock when accessing this object's members.
+ mutable Lock lock_;
+
+ typedef std::set<Resource*> ResourceSet;
+ ResourceSet live_resources_;
+
+ DISALLOW_COPY_AND_ASSIGN(ResourceTracker);
+};
+
+} // namespace pepper
+
+#endif // WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_TRACKER_H_
diff --git a/webkit/glue/plugins/pepper_string.h b/webkit/glue/plugins/pepper_string.h
new file mode 100644
index 0000000..1fc43c4f
--- /dev/null
+++ b/webkit/glue/plugins/pepper_string.h
@@ -0,0 +1,30 @@
+// 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 WEBKIT_GLUE_PLUGINS_PEPPER_STRING_H_
+#define WEBKIT_GLUE_PLUGINS_PEPPER_STRING_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+
+namespace pepper {
+
+class String : public base::RefCountedThreadSafe<String> {
+ public:
+ String(const char* str, uint32 len) : value_(str, len) {
+ }
+
+ const std::string& value() const { return value_; }
+
+ private:
+ std::string value_;
+
+ DISALLOW_COPY_AND_ASSIGN(String);
+};
+
+} // namespace pepper
+
+#endif // WEBKIT_GLUE_PLUGINS_PEPPER_STRING_H_
diff --git a/webkit/glue/plugins/pepper_var.cc b/webkit/glue/plugins/pepper_var.cc
new file mode 100644
index 0000000..3e11ff2
--- /dev/null
+++ b/webkit/glue/plugins/pepper_var.cc
@@ -0,0 +1,138 @@
+// 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 "webkit/glue/plugins/pepper_var.h"
+
+#include "third_party/ppapi/c/pp_var.h"
+#include "third_party/ppapi/c/ppb_var.h"
+#include "webkit/glue/plugins/pepper_string.h"
+
+namespace pepper {
+
+namespace {
+
+void AddRef(PP_Var var) {
+ if (var.type == PP_VarType_String) {
+ reinterpret_cast<String*>(var.value.as_id)->AddRef();
+ } else if (var.type == PP_VarType_Object) {
+ // TODO(implement objects).
+ }
+}
+
+void Release(PP_Var var) {
+ if (var.type == PP_VarType_String) {
+ reinterpret_cast<String*>(var.value.as_id)->Release();
+ } else if (var.type == PP_VarType_Object) {
+ // TODO(implement objects).
+ }
+}
+
+PP_Var VarFromUtf8(const char* data, uint32_t len) {
+ PP_Var ret;
+ ret.type = PP_VarType_String;
+ String* str = new String(data, len);
+ str->AddRef(); // This is for the caller, we return w/ a refcount of 1.
+ return ret;
+}
+
+const char* VarToUtf8(PP_Var var, uint32_t* len) {
+ if (var.type != PP_VarType_String) {
+ *len = 0;
+ return NULL;
+ }
+ const std::string& str =
+ reinterpret_cast<const String*>(var.value.as_id)->value();
+ *len = static_cast<uint32_t>(str.size());
+ if (str.empty())
+ return ""; // Don't return NULL on success.
+ return str.data();
+}
+
+bool HasProperty(PP_Var object,
+ PP_Var name,
+ PP_Var* exception) {
+ // TODO(brettw) implement this.
+ return false;
+}
+
+PP_Var GetProperty(PP_Var object,
+ PP_Var name,
+ PP_Var* exception) {
+ // TODO(brettw) implement this.
+ PP_Var ret;
+ ret.type = PP_VarType_Void;
+ return ret;
+}
+
+void GetAllPropertyNames(PP_Var object,
+ uint32_t* property_count,
+ PP_Var** properties,
+ PP_Var* exception) {
+ // TODO(brettw) implement this.
+}
+
+void SetProperty(PP_Var object,
+ PP_Var name,
+ PP_Var value,
+ PP_Var* exception) {
+ // TODO(brettw) implement this.
+}
+
+void RemoveProperty(PP_Var object,
+ PP_Var name,
+ PP_Var* exception) {
+ // TODO(brettw) implement this.
+}
+
+PP_Var Call(PP_Var object,
+ PP_Var method_name,
+ int32_t argc,
+ PP_Var* argv,
+ PP_Var* exception) {
+ // TODO(brettw) implement this.
+ PP_Var ret;
+ ret.type = PP_VarType_Void;
+ return ret;
+}
+
+PP_Var Construct(PP_Var object,
+ int32_t argc,
+ PP_Var* argv,
+ PP_Var* exception) {
+ // TODO(brettw) implement this.
+ PP_Var ret;
+ ret.type = PP_VarType_Void;
+ return ret;
+}
+
+PP_Var CreateObject(const PPP_Class* object_class,
+ void* object_data) {
+ // TODO(brettw) implement this.
+ PP_Var ret;
+ ret.type = PP_VarType_Void;
+ return ret;
+}
+
+const PPB_Var var_interface = {
+ &AddRef,
+ &Release,
+ &VarFromUtf8,
+ &VarToUtf8,
+ &HasProperty,
+ &GetProperty,
+ &GetAllPropertyNames,
+ &SetProperty,
+ &RemoveProperty,
+ &Call,
+ &Construct,
+ &CreateObject
+};
+
+} // namespace
+
+const PPB_Var* GetVarInterface() {
+ return &var_interface;
+}
+
+} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_var.h b/webkit/glue/plugins/pepper_var.h
new file mode 100644
index 0000000..c9d29fe
--- /dev/null
+++ b/webkit/glue/plugins/pepper_var.h
@@ -0,0 +1,19 @@
+// 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 WEBKIT_GLUE_PLUGINS_PEPPER_VAR_H_
+#define WEBKIT_GLUE_PLUGINS_PEPPER_VAR_H_
+
+typedef struct _ppb_Var PPB_Var;
+
+namespace pepper {
+
+// There's no class implementing Var since it could represent a number of
+// objects. Instead, we just expose a getter for the interface implemented in
+// the .cc file here.
+const PPB_Var* GetVarInterface();
+
+} // namespace pepper
+
+#endif // WEBKIT_GLUE_PLUGINS_PEPPER_VAR_H_
diff --git a/webkit/glue/plugins/pepper_webplugin_delegate_impl.cc b/webkit/glue/plugins/pepper_webplugin_delegate_impl.cc
new file mode 100644
index 0000000..473dd58
--- /dev/null
+++ b/webkit/glue/plugins/pepper_webplugin_delegate_impl.cc
@@ -0,0 +1,160 @@
+// 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 "webkit/glue/plugins/pepper_webplugin_delegate_impl.h"
+
+#include "base/logging.h"
+#include "base/ref_counted.h"
+#include "webkit/glue/plugins/pepper_device_context_2d.h"
+#include "webkit/glue/plugins/pepper_plugin_instance.h"
+#include "webkit/glue/plugins/pepper_plugin_module.h"
+#include "webkit/glue/plugins/webplugin.h"
+
+namespace pepper {
+
+WebPluginDelegateImpl::WebPluginDelegateImpl(PluginInstance* instance)
+ : instance_(instance),
+ web_plugin_(NULL) {
+}
+
+WebPluginDelegateImpl::~WebPluginDelegateImpl() {
+}
+
+// static
+WebPluginDelegateImpl* WebPluginDelegateImpl::Create(PluginDelegate* delegate,
+ const FilePath& filename) {
+ scoped_refptr<PluginModule> module = PluginModule::CreateModule(filename);
+ if (!module.get())
+ return NULL;
+
+ scoped_refptr<PluginInstance> instance = module->CreateInstance(delegate);
+ return new WebPluginDelegateImpl(instance.get());
+}
+
+bool WebPluginDelegateImpl::Initialize(
+ const GURL& url,
+ const std::vector<std::string>& arg_names,
+ const std::vector<std::string>& arg_values,
+ webkit_glue::WebPlugin* plugin,
+ bool load_manually) {
+ web_plugin_ = plugin;
+
+ if (!instance_->Initialize(arg_names, arg_values)) {
+ LOG(WARNING) << "Plugin instance initialization failed.";
+ return false;
+ }
+
+ // Declare we're in Windowless mode to WebKit.
+ web_plugin_->SetWindow(0);
+ return true;
+}
+
+void WebPluginDelegateImpl::PluginDestroyed() {
+ // TODO(brettw) we may need something like in the NPAPI version that checks
+ // for reentrancy and doesn't delete until later.
+ instance_->Delete();
+ delete this;
+}
+
+void WebPluginDelegateImpl::UpdateGeometry(const gfx::Rect& window_rect,
+ const gfx::Rect& clip_rect) {
+ window_rect_ = window_rect;
+ instance_->ViewChanged(window_rect, clip_rect);
+}
+
+void WebPluginDelegateImpl::Paint(WebKit::WebCanvas* canvas,
+ const gfx::Rect& rect) {
+ instance_->Paint(canvas, window_rect_, rect);
+}
+
+void WebPluginDelegateImpl::Print(gfx::NativeDrawingContext hdc) {
+}
+
+void WebPluginDelegateImpl::SetFocus(bool focused) {
+}
+
+bool WebPluginDelegateImpl::HandleInputEvent(const WebKit::WebInputEvent& event,
+ WebKit::WebCursorInfo* cursor) {
+ return instance_->HandleInputEvent(event, cursor);
+}
+
+NPObject* WebPluginDelegateImpl::GetPluginScriptableObject() {
+ return NULL;
+}
+
+void WebPluginDelegateImpl::DidFinishLoadWithReason(const GURL& url,
+ NPReason reason,
+ int notify_id) {
+}
+
+int WebPluginDelegateImpl::GetProcessId() {
+ return -1; // TODO(brettw) work out what this should do.
+}
+
+void WebPluginDelegateImpl::SendJavaScriptStream(const GURL& url,
+ const std::string& result,
+ bool success,
+ int notify_id) {
+}
+
+void WebPluginDelegateImpl::DidReceiveManualResponse(
+ const GURL& url,
+ const std::string& mime_type,
+ const std::string& headers,
+ uint32 expected_length,
+ uint32 last_modified) {
+}
+
+void WebPluginDelegateImpl::DidReceiveManualData(const char* buffer,
+ int length) {
+}
+
+void WebPluginDelegateImpl::DidFinishManualLoading() {
+}
+
+void WebPluginDelegateImpl::DidManualLoadFail() {
+}
+
+void WebPluginDelegateImpl::InstallMissingPlugin() {
+}
+
+webkit_glue::WebPluginResourceClient*
+WebPluginDelegateImpl::CreateResourceClient(unsigned long resource_id,
+ const GURL& url,
+ int notify_id) {
+ return NULL;
+}
+
+webkit_glue::WebPluginResourceClient*
+WebPluginDelegateImpl::CreateSeekableResourceClient(unsigned long resource_id,
+ int range_request_id) {
+ return NULL;
+}
+
+bool WebPluginDelegateImpl::SupportsFind() {
+ return false;
+}
+
+void WebPluginDelegateImpl::StartFind(const std::string& search_text,
+ bool case_sensitive,
+ int identifier) {
+}
+
+void WebPluginDelegateImpl::SelectFindResult(bool forward) {
+}
+
+void WebPluginDelegateImpl::StopFind() {
+}
+
+void WebPluginDelegateImpl::NumberOfFindResultsChanged(int total,
+ bool final_result) {
+}
+
+void WebPluginDelegateImpl::SelectedFindResultChanged(int index) {
+}
+
+void WebPluginDelegateImpl::Zoom(int factor) {
+}
+
+} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_webplugin_delegate_impl.h b/webkit/glue/plugins/pepper_webplugin_delegate_impl.h
new file mode 100644
index 0000000..a4bb58a
--- /dev/null
+++ b/webkit/glue/plugins/pepper_webplugin_delegate_impl.h
@@ -0,0 +1,86 @@
+// 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 WEBKIT_GLUE_PLUGINS_PEPPER_WEBPLUGIN_DELEGATE_IMPL_H_
+#define WEBKIT_GLUE_PLUGINS_PEPPER_WEBPLUGIN_DELEGATE_IMPL_H_
+
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+#include "gfx/rect.h"
+#include "webkit/glue/plugins/webplugin_delegate.h"
+
+namespace pepper {
+
+class DeviceContext2D;
+class PluginDelegate;
+class PluginInstance;
+
+class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
+ public:
+ virtual ~WebPluginDelegateImpl();
+
+ static WebPluginDelegateImpl* Create(PluginDelegate* delegate,
+ const FilePath& filename);
+
+ // webkit_glue::WebPluginDelegate implementation.
+ virtual bool Initialize(const GURL& url,
+ const std::vector<std::string>& arg_names,
+ const std::vector<std::string>& arg_values,
+ webkit_glue::WebPlugin* plugin,
+ bool load_manually);
+ virtual void PluginDestroyed();
+ virtual void UpdateGeometry(const gfx::Rect& window_rect,
+ const gfx::Rect& clip_rect);
+ virtual void Paint(WebKit::WebCanvas* canvas, const gfx::Rect& rect);
+ virtual void Print(gfx::NativeDrawingContext hdc);
+ virtual void SetFocus(bool focused);
+ virtual bool HandleInputEvent(const WebKit::WebInputEvent& event,
+ WebKit::WebCursorInfo* cursor);
+ virtual NPObject* GetPluginScriptableObject();
+ virtual void DidFinishLoadWithReason(const GURL& url, NPReason reason,
+ int notify_id);
+ virtual int GetProcessId();
+ virtual void SendJavaScriptStream(const GURL& url,
+ const std::string& result,
+ bool success,
+ int notify_id);
+ virtual void DidReceiveManualResponse(const GURL& url,
+ const std::string& mime_type,
+ const std::string& headers,
+ uint32 expected_length,
+ uint32 last_modified);
+ virtual void DidReceiveManualData(const char* buffer, int length);
+ virtual void DidFinishManualLoading();
+ virtual void DidManualLoadFail();
+ virtual void InstallMissingPlugin();
+ virtual webkit_glue::WebPluginResourceClient* CreateResourceClient(
+ unsigned long resource_id,
+ const GURL& url,
+ int notify_id);
+ virtual webkit_glue::WebPluginResourceClient* CreateSeekableResourceClient(
+ unsigned long resource_id, int range_request_id);
+ virtual bool SupportsFind();
+ virtual void StartFind(const std::string& search_text,
+ bool case_sensitive,
+ int identifier);
+ virtual void SelectFindResult(bool forward);
+ virtual void StopFind();
+ virtual void NumberOfFindResultsChanged(int total, bool final_result);
+ virtual void SelectedFindResultChanged(int index);
+ virtual void Zoom(int factor);
+
+ private:
+ WebPluginDelegateImpl(PluginInstance* instance);
+
+ scoped_refptr<PluginInstance> instance_;
+ webkit_glue::WebPlugin* web_plugin_;
+
+ gfx::Rect window_rect_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebPluginDelegateImpl);
+};
+
+} // namespace
+
+#endif // WEBKIT_GLUE_PLUGINS_PEPPER_WEBPLUGIN_DELEGATE_IMPL_H_
diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi
index e6b3a35..f7ee8ee 100644
--- a/webkit/glue/webkit_glue.gypi
+++ b/webkit/glue/webkit_glue.gypi
@@ -113,6 +113,7 @@
'<(DEPTH)/net/net.gyp:net',
'<(DEPTH)/third_party/icu/icu.gyp:icui18n',
'<(DEPTH)/third_party/icu/icu.gyp:icuuc',
+ '<(DEPTH)/third_party/ppapi/ppapi.gyp:ppapi_c',
'<(webkit_src_dir)/WebKit/chromium/WebKit.gyp:webkit',
'webkit_resources',
'webkit_strings',
@@ -159,6 +160,23 @@
'plugins/gtk_plugin_container_manager.cc',
'plugins/npapi_extension_thunk.cc',
'plugins/npapi_extension_thunk.h',
+ 'plugins/pepper_device_context_2d.cc',
+ 'plugins/pepper_device_context_2d.h',
+ 'plugins/pepper_image_data.cc',
+ 'plugins/pepper_image_data.h',
+ 'plugins/pepper_plugin_delegate.h',
+ 'plugins/pepper_plugin_instance.cc',
+ 'plugins/pepper_plugin_instance.h',
+ 'plugins/pepper_plugin_module.cc',
+ 'plugins/pepper_plugin_module.h',
+ 'plugins/pepper_resource_tracker.cc',
+ 'plugins/pepper_resource_tracker.h',
+ 'plugins/pepper_resource.cc',
+ 'plugins/pepper_resource.h',
+ 'plugins/pepper_var.cc',
+ 'plugins/pepper_var.h',
+ 'plugins/pepper_webplugin_delegate_impl.cc',
+ 'plugins/pepper_webplugin_delegate_impl.h',
'plugins/plugin_constants_win.h',
'plugins/plugin_host.cc',
'plugins/plugin_host.h',