diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-07 23:55:35 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-07 23:55:35 +0000 |
commit | e55badb64f610fa03504471ca8edd997a9d3f1b4 (patch) | |
tree | 18337beb82a19166cee0166faf9338124d5d6e78 /webkit | |
parent | 3d7a219946c1f718357d15cddb954cda5f2c92eb (diff) | |
download | chromium_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')
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', |