OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #define PEPPER_APIS_ENABLED 1 | 5 #define PEPPER_APIS_ENABLED 1 |
6 | 6 |
7 #include "chrome/renderer/webplugin_delegate_pepper.h" | 7 #include "chrome/renderer/webplugin_delegate_pepper.h" |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "app/gfx/blit.h" | 12 #include "app/gfx/blit.h" |
13 #include "base/file_util.h" | 13 #include "base/file_util.h" |
14 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
15 #include "base/process_util.h" | 15 #include "base/process_util.h" |
16 #include "base/scoped_ptr.h" | 16 #include "base/scoped_ptr.h" |
17 #include "base/stats_counters.h" | 17 #include "base/stats_counters.h" |
18 #include "base/string_util.h" | 18 #include "base/string_util.h" |
19 #include "chrome/common/render_messages.h" | 19 #include "chrome/common/render_messages.h" |
20 #include "chrome/renderer/render_thread.h" | 20 #include "chrome/renderer/render_thread.h" |
| 21 #include "third_party/npapi/bindings/npapi_extensions.h" |
21 #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" | 22 #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" |
22 #include "webkit/glue/glue_util.h" | 23 #include "webkit/glue/glue_util.h" |
23 #include "webkit/glue/pepper/pepper.h" | |
24 #include "webkit/glue/plugins/plugin_constants_win.h" | 24 #include "webkit/glue/plugins/plugin_constants_win.h" |
25 #include "webkit/glue/plugins/plugin_instance.h" | 25 #include "webkit/glue/plugins/plugin_instance.h" |
26 #include "webkit/glue/plugins/plugin_lib.h" | 26 #include "webkit/glue/plugins/plugin_lib.h" |
27 #include "webkit/glue/plugins/plugin_list.h" | 27 #include "webkit/glue/plugins/plugin_list.h" |
28 #include "webkit/glue/plugins/plugin_stream_url.h" | 28 #include "webkit/glue/plugins/plugin_stream_url.h" |
29 #include "webkit/glue/webkit_glue.h" | 29 #include "webkit/glue/webkit_glue.h" |
30 | 30 |
31 using webkit_glue::WebPlugin; | 31 using webkit_glue::WebPlugin; |
32 using webkit_glue::WebPluginDelegate; | 32 using webkit_glue::WebPluginDelegate; |
33 using webkit_glue::WebPluginResourceClient; | 33 using webkit_glue::WebPluginResourceClient; |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 return plugin_stream->AsResourceClient(); | 218 return plugin_stream->AsResourceClient(); |
219 } | 219 } |
220 | 220 |
221 std::string mime_type; | 221 std::string mime_type; |
222 NPAPI::PluginStreamUrl *stream = instance()->CreateStream( | 222 NPAPI::PluginStreamUrl *stream = instance()->CreateStream( |
223 resource_id, url, mime_type, notify_needed, | 223 resource_id, url, mime_type, notify_needed, |
224 reinterpret_cast<void*>(notify_data)); | 224 reinterpret_cast<void*>(notify_data)); |
225 return stream; | 225 return stream; |
226 } | 226 } |
227 | 227 |
| 228 NPError WebPluginDelegatePepper::Device2DQueryCapability(int32 capability, |
| 229 int32* value) { |
| 230 return NPERR_GENERIC_ERROR; |
| 231 } |
| 232 |
| 233 NPError WebPluginDelegatePepper::Device2DQueryConfig( |
| 234 const NPDeviceContext2DConfig* request, |
| 235 NPDeviceContext2DConfig* obtain) { |
| 236 return NPERR_GENERIC_ERROR; |
| 237 } |
| 238 |
| 239 NPError WebPluginDelegatePepper::Device2DInitializeContext( |
| 240 const NPDeviceContext2DConfig* config, |
| 241 NPDeviceContext2D* context) { |
| 242 int width = window_rect_.width(); |
| 243 int height = window_rect_.height(); |
| 244 uint32 buffer_size = width * height * kBytesPerPixel; |
| 245 |
| 246 // Allocate the transport DIB and the PlatformCanvas pointing to it. |
| 247 scoped_ptr<OpenPaintContext> paint_context(new OpenPaintContext); |
| 248 paint_context->transport_dib.reset( |
| 249 TransportDIB::Create(buffer_size, ++next_buffer_id)); |
| 250 if (!paint_context->transport_dib.get()) |
| 251 return NPERR_OUT_OF_MEMORY_ERROR; |
| 252 paint_context->canvas.reset( |
| 253 paint_context->transport_dib->GetPlatformCanvas(width, height)); |
| 254 if (!paint_context->canvas.get()) |
| 255 return NPERR_OUT_OF_MEMORY_ERROR; |
| 256 |
| 257 // Note that we need to get the address out of the bitmap rather than |
| 258 // using plugin_buffer_->memory(). The memory() is when the bitmap data |
| 259 // has had "Map" called on it. For Windows, this is separate than making a |
| 260 // bitmap using the shared section. |
| 261 const SkBitmap& plugin_bitmap = |
| 262 paint_context->canvas->getTopPlatformDevice().accessBitmap(true); |
| 263 SkAutoLockPixels locker(plugin_bitmap); |
| 264 |
| 265 // TODO(brettw) this theoretically shouldn't be necessary. But the |
| 266 // platform device on Windows will fill itself with green to help you |
| 267 // catch areas you didn't paint. |
| 268 plugin_bitmap.eraseARGB(0, 0, 0, 0); |
| 269 |
| 270 // Save the canvas to the output context structure and save the |
| 271 // OpenPaintContext for future reference. |
| 272 context->u.graphicsRgba.region = plugin_bitmap.getAddr32(0, 0); |
| 273 context->u.graphicsRgba.stride = width * kBytesPerPixel; |
| 274 context->u.graphicsRgba.dirty.left = 0; |
| 275 context->u.graphicsRgba.dirty.top = 0; |
| 276 context->u.graphicsRgba.dirty.right = width; |
| 277 context->u.graphicsRgba.dirty.bottom = height; |
| 278 open_paint_contexts_[context->u.graphicsRgba.region] = |
| 279 linked_ptr<OpenPaintContext>(paint_context.release()); |
| 280 return NPERR_NO_ERROR; |
| 281 } |
| 282 |
| 283 NPError WebPluginDelegatePepper::Device2DSetStateContext( |
| 284 NPDeviceContext2D* context, |
| 285 int32 state, |
| 286 int32 value) { |
| 287 return NPERR_GENERIC_ERROR; |
| 288 } |
| 289 |
| 290 NPError WebPluginDelegatePepper::Device2DGetStateContext( |
| 291 NPDeviceContext2D* context, |
| 292 int32 state, |
| 293 int32* value) { |
| 294 return NPERR_GENERIC_ERROR; |
| 295 } |
| 296 |
| 297 NPError WebPluginDelegatePepper::Device2DFlushContext( |
| 298 NPDeviceContext2D* context, |
| 299 NPDeviceFlushContextCallbackPtr callback, |
| 300 void* user_data) { |
| 301 // Get the bitmap data associated with the incoming context. |
| 302 OpenPaintContextMap::iterator found = open_paint_contexts_.find( |
| 303 context->u.graphicsRgba.region); |
| 304 if (found == open_paint_contexts_.end()) |
| 305 return NPERR_INVALID_PARAM; |
| 306 |
| 307 OpenPaintContext* paint_context = found->second.get(); |
| 308 |
| 309 // Draw the bitmap to the backing store. |
| 310 // |
| 311 // TODO(brettw) we can optimize this in the case where the entire canvas is |
| 312 // updated by actually taking ownership of the buffer and not telling the |
| 313 // plugin we're done using it. This wat we can avoid the copy when the entire |
| 314 // canvas has been updated. |
| 315 SkIRect src_rect = { context->u.graphicsRgba.dirty.left, |
| 316 context->u.graphicsRgba.dirty.top, |
| 317 context->u.graphicsRgba.dirty.right, |
| 318 context->u.graphicsRgba.dirty.bottom }; |
| 319 SkRect dest_rect = { SkIntToScalar(context->u.graphicsRgba.dirty.left), |
| 320 SkIntToScalar(context->u.graphicsRgba.dirty.top), |
| 321 SkIntToScalar(context->u.graphicsRgba.dirty.right), |
| 322 SkIntToScalar(context->u.graphicsRgba.dirty.bottom) }; |
| 323 SkCanvas committed_canvas(committed_bitmap_); |
| 324 |
| 325 // We want to replace the contents of the bitmap rather than blend. |
| 326 SkPaint paint; |
| 327 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
| 328 committed_canvas.drawBitmapRect( |
| 329 paint_context->canvas->getTopPlatformDevice().accessBitmap(false), |
| 330 &src_rect, dest_rect); |
| 331 |
| 332 committed_bitmap_.setIsOpaque(false); |
| 333 return NPERR_NO_ERROR; |
| 334 } |
| 335 |
| 336 NPError WebPluginDelegatePepper::Device2DDestroyContext( |
| 337 NPDeviceContext2D* context) { |
| 338 OpenPaintContextMap::iterator found = open_paint_contexts_.find( |
| 339 context->u.graphicsRgba.region); |
| 340 if (found == open_paint_contexts_.end()) |
| 341 return NPERR_INVALID_PARAM; |
| 342 |
| 343 open_paint_contexts_.erase(found); |
| 344 return NPERR_NO_ERROR; |
| 345 } |
| 346 |
228 bool WebPluginDelegatePepper::IsPluginDelegateWindow( | 347 bool WebPluginDelegatePepper::IsPluginDelegateWindow( |
229 gfx::NativeWindow window) { | 348 gfx::NativeWindow window) { |
230 return false; | 349 return false; |
231 } | 350 } |
232 | 351 |
233 bool WebPluginDelegatePepper::GetPluginNameFromWindow( | 352 bool WebPluginDelegatePepper::GetPluginNameFromWindow( |
234 gfx::NativeWindow window, std::wstring *plugin_name) { | 353 gfx::NativeWindow window, std::wstring *plugin_name) { |
235 return false; | 354 return false; |
236 } | 355 } |
237 | 356 |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 BuildCharEvent(&event, &npevent); | 517 BuildCharEvent(&event, &npevent); |
399 break; | 518 break; |
400 case NPEventType_Minimize: | 519 case NPEventType_Minimize: |
401 case NPEventType_Focus: | 520 case NPEventType_Focus: |
402 case NPEventType_Device: | 521 case NPEventType_Device: |
403 NOTIMPLEMENTED(); | 522 NOTIMPLEMENTED(); |
404 break; | 523 break; |
405 } | 524 } |
406 return instance()->NPP_HandleEvent(&npevent) != 0; | 525 return instance()->NPP_HandleEvent(&npevent) != 0; |
407 } | 526 } |
408 | |
409 NPError WebPluginDelegatePepper::InitializeRenderContext( | |
410 NPRenderType type, NPRenderContext* context) { | |
411 switch (type) { | |
412 case NPRenderGraphicsRGBA: { | |
413 int width = window_rect_.width(); | |
414 int height = window_rect_.height(); | |
415 uint32 buffer_size = width * height * kBytesPerPixel; | |
416 | |
417 // Allocate the transport DIB and the PlatformCanvas pointing to it. | |
418 scoped_ptr<OpenPaintContext> paint_context(new OpenPaintContext); | |
419 paint_context->transport_dib.reset( | |
420 TransportDIB::Create(buffer_size, ++next_buffer_id)); | |
421 if (!paint_context->transport_dib.get()) | |
422 return NPERR_OUT_OF_MEMORY_ERROR; | |
423 paint_context->canvas.reset( | |
424 paint_context->transport_dib->GetPlatformCanvas(width, height)); | |
425 if (!paint_context->canvas.get()) | |
426 return NPERR_OUT_OF_MEMORY_ERROR; | |
427 | |
428 // Note that we need to get the address out of the bitmap rather than | |
429 // using plugin_buffer_->memory(). The memory() is when the bitmap data | |
430 // has had "Map" called on it. For Windows, this is separate than making a | |
431 // bitmap using the shared section. | |
432 const SkBitmap& plugin_bitmap = | |
433 paint_context->canvas->getTopPlatformDevice().accessBitmap(true); | |
434 SkAutoLockPixels locker(plugin_bitmap); | |
435 | |
436 // TODO(brettw) this theoretically shouldn't be necessary. But the | |
437 // platform device on Windows will fill itself with green to help you | |
438 // catch areas you didn't paint. | |
439 plugin_bitmap.eraseARGB(0, 0, 0, 0); | |
440 | |
441 // Save the canvas to the output context structure and save the | |
442 // OpenPaintContext for future reference. | |
443 context->u.graphicsRgba.region = plugin_bitmap.getAddr32(0, 0); | |
444 context->u.graphicsRgba.stride = width * kBytesPerPixel; | |
445 context->u.graphicsRgba.dirty.left = 0; | |
446 context->u.graphicsRgba.dirty.top = 0; | |
447 context->u.graphicsRgba.dirty.right = width; | |
448 context->u.graphicsRgba.dirty.bottom = height; | |
449 open_paint_contexts_[context->u.graphicsRgba.region] = | |
450 linked_ptr<OpenPaintContext>(paint_context.release()); | |
451 return NPERR_NO_ERROR; | |
452 } | |
453 default: | |
454 return NPERR_GENERIC_ERROR; | |
455 } | |
456 } | |
457 | |
458 NPError WebPluginDelegatePepper::DestroyRenderContext( | |
459 NPRenderContext* context) { | |
460 OpenPaintContextMap::iterator found = open_paint_contexts_.find( | |
461 context->u.graphicsRgba.region); | |
462 if (found == open_paint_contexts_.end()) | |
463 return NPERR_INVALID_PARAM; | |
464 | |
465 open_paint_contexts_.erase(found); | |
466 return NPERR_NO_ERROR; | |
467 } | |
468 | |
469 NPError WebPluginDelegatePepper::FlushRenderContext(NPRenderContext* context) { | |
470 // Get the bitmap data associated with the incoming context. | |
471 OpenPaintContextMap::iterator found = open_paint_contexts_.find( | |
472 context->u.graphicsRgba.region); | |
473 if (found == open_paint_contexts_.end()) | |
474 return NPERR_INVALID_PARAM; | |
475 | |
476 OpenPaintContext* paint_context = found->second.get(); | |
477 | |
478 // Draw the bitmap to the backing store. | |
479 // | |
480 // TODO(brettw) we can optimize this in the case where the entire canvas is | |
481 // updated by actually taking ownership of the buffer and not telling the | |
482 // plugin we're done using it. This wat we can avoid the copy when the entire | |
483 // canvas has been updated. | |
484 SkIRect src_rect = { context->u.graphicsRgba.dirty.left, | |
485 context->u.graphicsRgba.dirty.top, | |
486 context->u.graphicsRgba.dirty.right, | |
487 context->u.graphicsRgba.dirty.bottom }; | |
488 SkRect dest_rect = { SkIntToScalar(context->u.graphicsRgba.dirty.left), | |
489 SkIntToScalar(context->u.graphicsRgba.dirty.top), | |
490 SkIntToScalar(context->u.graphicsRgba.dirty.right), | |
491 SkIntToScalar(context->u.graphicsRgba.dirty.bottom) }; | |
492 SkCanvas committed_canvas(committed_bitmap_); | |
493 | |
494 // We want to replace the contents of the bitmap rather than blend. | |
495 SkPaint paint; | |
496 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | |
497 committed_canvas.drawBitmapRect( | |
498 paint_context->canvas->getTopPlatformDevice().accessBitmap(false), | |
499 &src_rect, dest_rect); | |
500 | |
501 committed_bitmap_.setIsOpaque(false); | |
502 return NPERR_NO_ERROR; | |
503 } | |
504 | |
505 NPError WebPluginDelegatePepper::OpenFileInSandbox(const char* file_name, | |
506 void** handle) { | |
507 *handle = NULL; | |
508 | |
509 #if defined(OS_WIN) | |
510 FilePath file_path(UTF8ToUTF16(file_name)); | |
511 #elif defined(OS_POSIX) | |
512 FilePath file_path(file_name); | |
513 #endif | |
514 | |
515 ViewMsg_OpenFileForPluginResponse_Params result; | |
516 RenderThread::current()->Send(new ViewMsg_OpenFileForPlugin( | |
517 file_path, &result)); | |
518 | |
519 #if defined(OS_WIN) | |
520 if (!result.file_handle) | |
521 return NPERR_INVALID_PARAM; | |
522 *handle = result.file_handle; | |
523 #elif defined(OS_POSIX) | |
524 if (result.file_handle.fd == -1) | |
525 return NPERR_INVALID_PARAM; | |
526 *reinterpret_cast<int*>(handle) = result.file_handle.fd; | |
527 #endif | |
528 | |
529 return NPERR_NO_ERROR; | |
530 } | |
OLD | NEW |