| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 #include "chrome/plugin/webplugin_proxy.h" | 5 #include "chrome/plugin/webplugin_proxy.h" |
| 6 | 6 |
| 7 #include "base/gfx/gdi_util.h" | 7 #include "base/gfx/gdi_util.h" |
| 8 #include "base/scoped_handle.h" | 8 #include "base/scoped_handle.h" |
| 9 #include "base/shared_memory.h" | 9 #include "base/shared_memory.h" |
| 10 #include "base/singleton.h" | 10 #include "base/singleton.h" |
| 11 #include "base/waitable_event.h" | 11 #include "base/waitable_event.h" |
| 12 #include "chrome/common/gfx/chrome_canvas.h" | 12 #include "chrome/common/gfx/chrome_canvas.h" |
| 13 #include "chrome/common/plugin_messages.h" | 13 #include "chrome/common/plugin_messages.h" |
| 14 #include "chrome/common/win_util.h" | 14 #include "chrome/common/win_util.h" |
| 15 #include "chrome/plugin/npobject_proxy.h" | 15 #include "chrome/plugin/npobject_proxy.h" |
| 16 #include "chrome/plugin/npobject_util.h" | 16 #include "chrome/plugin/npobject_util.h" |
| 17 #include "chrome/plugin/plugin_channel.h" | 17 #include "chrome/plugin/plugin_channel.h" |
| 18 #include "chrome/plugin/plugin_thread.h" | 18 #include "chrome/plugin/plugin_thread.h" |
| 19 #include "chrome/plugin/webplugin_delegate_stub.h" | 19 #include "chrome/plugin/webplugin_delegate_stub.h" |
| 20 #include "skia/ext/platform_device.h" | 20 #include "skia/ext/platform_device.h" |
| 21 #include "webkit/glue/plugins/webplugin_delegate_impl.h" | 21 #include "webkit/glue/webplugin_delegate.h" |
| 22 | 22 |
| 23 typedef std::map<CPBrowsingContext, WebPluginProxy*> ContextMap; | 23 typedef std::map<CPBrowsingContext, WebPluginProxy*> ContextMap; |
| 24 static ContextMap& GetContextMap() { | 24 static ContextMap& GetContextMap() { |
| 25 return *Singleton<ContextMap>::get(); | 25 return *Singleton<ContextMap>::get(); |
| 26 } | 26 } |
| 27 | 27 |
| 28 WebPluginProxy::WebPluginProxy( | 28 WebPluginProxy::WebPluginProxy( |
| 29 PluginChannel* channel, | 29 PluginChannel* channel, |
| 30 int route_id, | 30 int route_id, |
| 31 WebPluginDelegateImpl* delegate, | 31 WebPluginDelegate* delegate, |
| 32 HANDLE modal_dialog_event) | 32 HANDLE modal_dialog_event) |
| 33 : channel_(channel), | 33 : channel_(channel), |
| 34 route_id_(route_id), | 34 route_id_(route_id), |
| 35 cp_browsing_context_(0), | 35 cp_browsing_context_(0), |
| 36 window_npobject_(NULL), | 36 window_npobject_(NULL), |
| 37 plugin_element_(NULL), | 37 plugin_element_(NULL), |
| 38 delegate_(delegate), | 38 delegate_(delegate), |
| 39 waiting_for_paint_(false), | 39 waiting_for_paint_(false), |
| 40 #pragma warning(suppress: 4355) // can use this | 40 #pragma warning(suppress: 4355) // can use this |
| 41 runnable_method_factory_(this), | 41 runnable_method_factory_(this), |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 Send(new PluginHostMsg_SetWindow(route_id_, window, | 102 Send(new PluginHostMsg_SetWindow(route_id_, window, |
| 103 pump_messages_event_for_renderer)); | 103 pump_messages_event_for_renderer)); |
| 104 } | 104 } |
| 105 | 105 |
| 106 void WebPluginProxy::CancelResource(int id) { | 106 void WebPluginProxy::CancelResource(int id) { |
| 107 Send(new PluginHostMsg_CancelResource(route_id_, id)); | 107 Send(new PluginHostMsg_CancelResource(route_id_, id)); |
| 108 resource_clients_.erase(id); | 108 resource_clients_.erase(id); |
| 109 } | 109 } |
| 110 | 110 |
| 111 void WebPluginProxy::Invalidate() { | 111 void WebPluginProxy::Invalidate() { |
| 112 gfx::Rect rect(0, 0, delegate_->rect().width(), delegate_->rect().height()); | 112 gfx::Rect rect(0, 0, |
| 113 delegate_->GetRect().width(), |
| 114 delegate_->GetRect().height()); |
| 113 InvalidateRect(rect); | 115 InvalidateRect(rect); |
| 114 } | 116 } |
| 115 | 117 |
| 116 void WebPluginProxy::InvalidateRect(const gfx::Rect& rect) { | 118 void WebPluginProxy::InvalidateRect(const gfx::Rect& rect) { |
| 117 damaged_rect_ = damaged_rect_.Union(rect); | 119 damaged_rect_ = damaged_rect_.Union(rect); |
| 118 // Ignore NPN_InvalidateRect calls with empty rects. Also don't send an | 120 // Ignore NPN_InvalidateRect calls with empty rects. Also don't send an |
| 119 // invalidate if it's outside the clipping region, since if we did it won't | 121 // invalidate if it's outside the clipping region, since if we did it won't |
| 120 // lead to a paint and we'll be stuck waiting forever for a DidPaint response. | 122 // lead to a paint and we'll be stuck waiting forever for a DidPaint response. |
| 121 if (rect.IsEmpty() || !delegate_->clip_rect().Intersects(rect)) | 123 if (rect.IsEmpty() || !delegate_->GetClipRect().Intersects(rect)) |
| 122 return; | 124 return; |
| 123 | 125 |
| 124 // Only send a single InvalidateRect message at a time. From DidPaint we | 126 // Only send a single InvalidateRect message at a time. From DidPaint we |
| 125 // will dispatch an additional InvalidateRect message if necessary. | 127 // will dispatch an additional InvalidateRect message if necessary. |
| 126 if (!waiting_for_paint_) { | 128 if (!waiting_for_paint_) { |
| 127 waiting_for_paint_ = true; | 129 waiting_for_paint_ = true; |
| 128 // Invalidates caused by calls to NPN_InvalidateRect/NPN_InvalidateRgn | 130 // Invalidates caused by calls to NPN_InvalidateRect/NPN_InvalidateRgn |
| 129 // need to be painted asynchronously as per the NPAPI spec. | 131 // need to be painted asynchronously as per the NPAPI spec. |
| 130 MessageLoop::current()->PostTask(FROM_HERE, | 132 MessageLoop::current()->PostTask(FROM_HERE, |
| 131 runnable_method_factory_.NewRunnableMethod( | 133 runnable_method_factory_.NewRunnableMethod( |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 bool notify, const char* url, | 262 bool notify, const char* url, |
| 261 void* notify_data, bool popups_allowed) { | 263 void* notify_data, bool popups_allowed) { |
| 262 if (!url) { | 264 if (!url) { |
| 263 NOTREACHED(); | 265 NOTREACHED(); |
| 264 return; | 266 return; |
| 265 } | 267 } |
| 266 | 268 |
| 267 if (!target && (0 == _strcmpi(method, "GET"))) { | 269 if (!target && (0 == _strcmpi(method, "GET"))) { |
| 268 // Please refer to https://bugzilla.mozilla.org/show_bug.cgi?id=366082 | 270 // Please refer to https://bugzilla.mozilla.org/show_bug.cgi?id=366082 |
| 269 // for more details on this. | 271 // for more details on this. |
| 270 if (delegate_->quirks() & | 272 if (delegate_->GetQuirks() & |
| 271 WebPluginDelegateImpl::PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS) { | 273 WebPluginDelegate::PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS) { |
| 272 GURL request_url(url); | 274 GURL request_url(url); |
| 273 if (!request_url.SchemeIs("http") && !request_url.SchemeIs("https") && | 275 if (!request_url.SchemeIs("http") && !request_url.SchemeIs("https") && |
| 274 !request_url.SchemeIs("ftp")) { | 276 !request_url.SchemeIs("ftp")) { |
| 275 return; | 277 return; |
| 276 } | 278 } |
| 277 } | 279 } |
| 278 } | 280 } |
| 279 | 281 |
| 280 PluginHostMsg_URLRequest_Params params; | 282 PluginHostMsg_URLRequest_Params params; |
| 281 params.method = method; | 283 params.method = method; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 297 Send(new PluginHostMsg_URLRequest(route_id_, params)); | 299 Send(new PluginHostMsg_URLRequest(route_id_, params)); |
| 298 } | 300 } |
| 299 | 301 |
| 300 void WebPluginProxy::Paint(const gfx::Rect& rect) { | 302 void WebPluginProxy::Paint(const gfx::Rect& rect) { |
| 301 if (!windowless_hdc_) | 303 if (!windowless_hdc_) |
| 302 return; | 304 return; |
| 303 | 305 |
| 304 // Clear the damaged area so that if the plugin doesn't paint there we won't | 306 // Clear the damaged area so that if the plugin doesn't paint there we won't |
| 305 // end up with the old values. | 307 // end up with the old values. |
| 306 gfx::Rect offset_rect = rect; | 308 gfx::Rect offset_rect = rect; |
| 307 offset_rect.Offset(delegate_->rect().x(), delegate_->rect().y()); | 309 offset_rect.Offset(delegate_->GetRect().origin()); |
| 308 if (!background_hdc_) { | 310 if (!background_hdc_) { |
| 309 FillRect(windowless_hdc_, &offset_rect.ToRECT(), | 311 FillRect(windowless_hdc_, &offset_rect.ToRECT(), |
| 310 static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH))); | 312 static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH))); |
| 311 } else { | 313 } else { |
| 312 BitBlt(windowless_hdc_, offset_rect.x(), offset_rect.y(), | 314 BitBlt(windowless_hdc_, offset_rect.x(), offset_rect.y(), |
| 313 offset_rect.width(), offset_rect.height(), background_hdc_, | 315 offset_rect.width(), offset_rect.height(), background_hdc_, |
| 314 rect.x(), rect.y(), SRCCOPY); | 316 rect.x(), rect.y(), SRCCOPY); |
| 315 } | 317 } |
| 316 | 318 |
| 317 // Before we send the invalidate, paint so that renderer uses the updated | 319 // Before we send the invalidate, paint so that renderer uses the updated |
| 318 // bitmap. | 320 // bitmap. |
| 319 delegate_->Paint(windowless_hdc_, offset_rect); | 321 delegate_->Paint(windowless_hdc_, offset_rect); |
| 320 } | 322 } |
| 321 | 323 |
| 322 void WebPluginProxy::UpdateGeometry( | 324 void WebPluginProxy::UpdateGeometry( |
| 323 const gfx::Rect& window_rect, | 325 const gfx::Rect& window_rect, |
| 324 const gfx::Rect& clip_rect, | 326 const gfx::Rect& clip_rect, |
| 325 const base::SharedMemoryHandle& windowless_buffer, | 327 const base::SharedMemoryHandle& windowless_buffer, |
| 326 const base::SharedMemoryHandle& background_buffer) { | 328 const base::SharedMemoryHandle& background_buffer) { |
| 327 gfx::Rect old = delegate_->rect(); | 329 gfx::Rect old = delegate_->GetRect(); |
| 328 gfx::Rect old_clip_rect = delegate_->clip_rect(); | 330 gfx::Rect old_clip_rect = delegate_->GetClipRect(); |
| 329 | 331 |
| 330 bool moved = delegate_->rect().x() != window_rect.x() || | 332 bool moved = old.x() != window_rect.x() || old.y() != window_rect.y(); |
| 331 delegate_->rect().y() != window_rect.y(); | |
| 332 delegate_->UpdateGeometry(window_rect, clip_rect); | 333 delegate_->UpdateGeometry(window_rect, clip_rect); |
| 333 if (windowless_buffer) { | 334 if (windowless_buffer) { |
| 334 // The plugin's rect changed, so now we have a new buffer to draw into. | 335 // The plugin's rect changed, so now we have a new buffer to draw into. |
| 335 SetWindowlessBuffer(windowless_buffer, background_buffer); | 336 SetWindowlessBuffer(windowless_buffer, background_buffer); |
| 336 } else if (moved) { | 337 } else if (moved) { |
| 337 // The plugin moved, so update our world transform. | 338 // The plugin moved, so update our world transform. |
| 338 UpdateTransform(); | 339 UpdateTransform(); |
| 339 } | 340 } |
| 340 // Send over any pending invalidates which occured when the plugin was | 341 // Send over any pending invalidates which occured when the plugin was |
| 341 // off screen. | 342 // off screen. |
| 342 if (delegate_->windowless() && !clip_rect.IsEmpty() && | 343 if (delegate_->IsWindowless() && !clip_rect.IsEmpty() && |
| 343 old_clip_rect.IsEmpty() && !damaged_rect_.IsEmpty()) { | 344 old_clip_rect.IsEmpty() && !damaged_rect_.IsEmpty()) { |
| 344 InvalidateRect(damaged_rect_); | 345 InvalidateRect(damaged_rect_); |
| 345 } | 346 } |
| 346 } | 347 } |
| 347 | 348 |
| 348 void WebPluginProxy::SetWindowlessBuffer( | 349 void WebPluginProxy::SetWindowlessBuffer( |
| 349 const base::SharedMemoryHandle& windowless_buffer, | 350 const base::SharedMemoryHandle& windowless_buffer, |
| 350 const base::SharedMemoryHandle& background_buffer) { | 351 const base::SharedMemoryHandle& background_buffer) { |
| 351 // Convert the shared memory handle to a handle that works in our process, | 352 // Convert the shared memory handle to a handle that works in our process, |
| 352 // and then use that to create an HDC. | 353 // and then use that to create an HDC. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 370 shared_section->Set(win_util::GetSectionFromProcess( | 371 shared_section->Set(win_util::GetSectionFromProcess( |
| 371 buffer, channel_->renderer_handle(), false)); | 372 buffer, channel_->renderer_handle(), false)); |
| 372 if (shared_section->Get() == NULL) { | 373 if (shared_section->Get() == NULL) { |
| 373 NOTREACHED(); | 374 NOTREACHED(); |
| 374 return; | 375 return; |
| 375 } | 376 } |
| 376 | 377 |
| 377 void* data = NULL; | 378 void* data = NULL; |
| 378 HDC screen_dc = GetDC(NULL); | 379 HDC screen_dc = GetDC(NULL); |
| 379 BITMAPINFOHEADER bitmap_header; | 380 BITMAPINFOHEADER bitmap_header; |
| 380 gfx::CreateBitmapHeader(delegate_->rect().width(), | 381 gfx::CreateBitmapHeader(delegate_->GetRect().width(), |
| 381 delegate_->rect().height(), | 382 delegate_->GetRect().height(), |
| 382 &bitmap_header); | 383 &bitmap_header); |
| 383 bitmap->Set(CreateDIBSection( | 384 bitmap->Set(CreateDIBSection( |
| 384 screen_dc, reinterpret_cast<const BITMAPINFO*>(&bitmap_header), | 385 screen_dc, reinterpret_cast<const BITMAPINFO*>(&bitmap_header), |
| 385 DIB_RGB_COLORS, &data, shared_section->Get(), 0)); | 386 DIB_RGB_COLORS, &data, shared_section->Get(), 0)); |
| 386 ReleaseDC(NULL, screen_dc); | 387 ReleaseDC(NULL, screen_dc); |
| 387 if (bitmap->Get() == NULL) { | 388 if (bitmap->Get() == NULL) { |
| 388 NOTREACHED(); | 389 NOTREACHED(); |
| 389 return; | 390 return; |
| 390 } | 391 } |
| 391 | 392 |
| 392 hdc->Set(CreateCompatibleDC(NULL)); | 393 hdc->Set(CreateCompatibleDC(NULL)); |
| 393 if (hdc->Get() == NULL) { | 394 if (hdc->Get() == NULL) { |
| 394 NOTREACHED(); | 395 NOTREACHED(); |
| 395 return; | 396 return; |
| 396 } | 397 } |
| 397 | 398 |
| 398 skia::PlatformDeviceWin::InitializeDC(hdc->Get()); | 399 skia::PlatformDeviceWin::InitializeDC(hdc->Get()); |
| 399 SelectObject(hdc->Get(), bitmap->Get()); | 400 SelectObject(hdc->Get(), bitmap->Get()); |
| 400 } | 401 } |
| 401 | 402 |
| 402 void WebPluginProxy::UpdateTransform() { | 403 void WebPluginProxy::UpdateTransform() { |
| 403 if (!windowless_hdc_) | 404 if (!windowless_hdc_) |
| 404 return; | 405 return; |
| 405 | 406 |
| 406 XFORM xf; | 407 XFORM xf; |
| 407 xf.eDx = static_cast<FLOAT>(-delegate_->rect().x()); | 408 xf.eDx = static_cast<FLOAT>(-delegate_->GetRect().x()); |
| 408 xf.eDy = static_cast<FLOAT>(-delegate_->rect().y()); | 409 xf.eDy = static_cast<FLOAT>(-delegate_->GetRect().y()); |
| 409 xf.eM11 = 1; | 410 xf.eM11 = 1; |
| 410 xf.eM21 = 0; | 411 xf.eM21 = 0; |
| 411 xf.eM12 = 0; | 412 xf.eM12 = 0; |
| 412 xf.eM22 = 1; | 413 xf.eM22 = 1; |
| 413 SetWorldTransform(windowless_hdc_, &xf); | 414 SetWorldTransform(windowless_hdc_, &xf); |
| 414 } | 415 } |
| 415 | 416 |
| 416 void WebPluginProxy::CancelDocumentLoad() { | 417 void WebPluginProxy::CancelDocumentLoad() { |
| 417 Send(new PluginHostMsg_CancelDocumentLoad(route_id_)); | 418 Send(new PluginHostMsg_CancelDocumentLoad(route_id_)); |
| 418 } | 419 } |
| 419 | 420 |
| 420 void WebPluginProxy::InitiateHTTPRangeRequest(const char* url, | 421 void WebPluginProxy::InitiateHTTPRangeRequest(const char* url, |
| 421 const char* range_info, | 422 const char* range_info, |
| 422 void* existing_stream, | 423 void* existing_stream, |
| 423 bool notify_needed, | 424 bool notify_needed, |
| 424 HANDLE notify_data) { | 425 HANDLE notify_data) { |
| 425 | 426 |
| 426 Send(new PluginHostMsg_InitiateHTTPRangeRequest(route_id_, url, | 427 Send(new PluginHostMsg_InitiateHTTPRangeRequest(route_id_, url, |
| 427 range_info, existing_stream, | 428 range_info, existing_stream, |
| 428 notify_needed, notify_data)); | 429 notify_needed, notify_data)); |
| 429 } | 430 } |
| 430 | 431 |
| 431 void WebPluginProxy::OnPaint(const gfx::Rect& damaged_rect) { | 432 void WebPluginProxy::OnPaint(const gfx::Rect& damaged_rect) { |
| 432 Paint(damaged_rect); | 433 Paint(damaged_rect); |
| 433 Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect)); | 434 Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect)); |
| 434 } | 435 } |
| OLD | NEW |