| 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" | |
| 8 #include "base/scoped_handle.h" | 7 #include "base/scoped_handle.h" |
| 9 #include "base/shared_memory.h" | 8 #include "base/shared_memory.h" |
| 10 #include "base/singleton.h" | 9 #include "base/singleton.h" |
| 11 #include "base/waitable_event.h" | 10 #include "base/waitable_event.h" |
| 11 #include "build/build_config.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/url_constants.h" | 14 #include "chrome/common/url_constants.h" |
| 15 #include "chrome/common/win_util.h" | |
| 16 #include "chrome/plugin/npobject_proxy.h" | 15 #include "chrome/plugin/npobject_proxy.h" |
| 17 #include "chrome/plugin/npobject_util.h" | 16 #include "chrome/plugin/npobject_util.h" |
| 18 #include "chrome/plugin/plugin_channel.h" | 17 #include "chrome/plugin/plugin_channel.h" |
| 19 #include "chrome/plugin/plugin_thread.h" | 18 #include "chrome/plugin/plugin_thread.h" |
| 20 #include "chrome/plugin/webplugin_delegate_stub.h" | 19 #include "chrome/plugin/webplugin_delegate_stub.h" |
| 21 #include "skia/ext/platform_device.h" | 20 #include "skia/ext/platform_device.h" |
| 22 #include "webkit/glue/webplugin_delegate.h" | 21 #include "webkit/glue/webplugin_delegate.h" |
| 23 | 22 |
| 23 #if defined(OS_WIN) |
| 24 #include "base/gfx/gdi_util.h" |
| 25 #include "chrome/common/win_util.h" |
| 26 #endif |
| 27 |
| 24 typedef std::map<CPBrowsingContext, WebPluginProxy*> ContextMap; | 28 typedef std::map<CPBrowsingContext, WebPluginProxy*> ContextMap; |
| 25 static ContextMap& GetContextMap() { | 29 static ContextMap& GetContextMap() { |
| 26 return *Singleton<ContextMap>::get(); | 30 return *Singleton<ContextMap>::get(); |
| 27 } | 31 } |
| 28 | 32 |
| 29 WebPluginProxy::WebPluginProxy( | 33 WebPluginProxy::WebPluginProxy( |
| 30 PluginChannel* channel, | 34 PluginChannel* channel, |
| 31 int route_id, | 35 int route_id, |
| 32 WebPluginDelegate* delegate) | 36 WebPluginDelegate* delegate) |
| 33 : channel_(channel), | 37 : channel_(channel), |
| 34 route_id_(route_id), | 38 route_id_(route_id), |
| 35 cp_browsing_context_(0), | 39 cp_browsing_context_(0), |
| 36 window_npobject_(NULL), | 40 window_npobject_(NULL), |
| 37 plugin_element_(NULL), | 41 plugin_element_(NULL), |
| 38 delegate_(delegate), | 42 delegate_(delegate), |
| 39 waiting_for_paint_(false), | 43 waiting_for_paint_(false), |
| 40 #pragma warning(suppress: 4355) // can use this | 44 ALLOW_THIS_IN_INITIALIZER_LIST(runnable_method_factory_(this)) |
| 41 runnable_method_factory_(this) { | 45 { |
| 42 } | 46 } |
| 43 | 47 |
| 44 WebPluginProxy::~WebPluginProxy() { | 48 WebPluginProxy::~WebPluginProxy() { |
| 45 if (cp_browsing_context_) | 49 if (cp_browsing_context_) |
| 46 GetContextMap().erase(cp_browsing_context_); | 50 GetContextMap().erase(cp_browsing_context_); |
| 47 } | 51 } |
| 48 | 52 |
| 49 bool WebPluginProxy::Send(IPC::Message* msg) { | 53 bool WebPluginProxy::Send(IPC::Message* msg) { |
| 50 return channel_->Send(msg); | 54 return channel_->Send(msg); |
| 51 } | 55 } |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 const char* target, unsigned int len, | 253 const char* target, unsigned int len, |
| 250 const char* buf, bool is_file_data, | 254 const char* buf, bool is_file_data, |
| 251 bool notify, const char* url, | 255 bool notify, const char* url, |
| 252 intptr_t notify_data, | 256 intptr_t notify_data, |
| 253 bool popups_allowed) { | 257 bool popups_allowed) { |
| 254 if (!url) { | 258 if (!url) { |
| 255 NOTREACHED(); | 259 NOTREACHED(); |
| 256 return; | 260 return; |
| 257 } | 261 } |
| 258 | 262 |
| 259 if (!target && (0 == _strcmpi(method, "GET"))) { | 263 if (!target && (0 == base::strcasecmp(method, "GET"))) { |
| 260 // Please refer to https://bugzilla.mozilla.org/show_bug.cgi?id=366082 | 264 // Please refer to https://bugzilla.mozilla.org/show_bug.cgi?id=366082 |
| 261 // for more details on this. | 265 // for more details on this. |
| 266 #if defined(OS_WIN) |
| 262 if (delegate_->GetQuirks() & | 267 if (delegate_->GetQuirks() & |
| 263 WebPluginDelegate::PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS) { | 268 WebPluginDelegate::PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS) { |
| 264 GURL request_url(url); | 269 GURL request_url(url); |
| 265 if (!request_url.SchemeIs(chrome::kHttpScheme) && | 270 if (!request_url.SchemeIs(chrome::kHttpScheme) && |
| 266 !request_url.SchemeIs(chrome::kHttpsScheme) && | 271 !request_url.SchemeIs(chrome::kHttpsScheme) && |
| 267 !request_url.SchemeIs(chrome::kFtpScheme)) { | 272 !request_url.SchemeIs(chrome::kFtpScheme)) { |
| 268 return; | 273 return; |
| 269 } | 274 } |
| 270 } | 275 } |
| 276 #else |
| 277 // TODO(port): we need a GetQuirks() on our delegate impl. |
| 278 NOTIMPLEMENTED(); |
| 279 #endif |
| 271 } | 280 } |
| 272 | 281 |
| 273 PluginHostMsg_URLRequest_Params params; | 282 PluginHostMsg_URLRequest_Params params; |
| 274 params.method = method; | 283 params.method = method; |
| 275 params.is_javascript_url = is_javascript_url; | 284 params.is_javascript_url = is_javascript_url; |
| 276 if (target) | 285 if (target) |
| 277 params.target = std::string(target); | 286 params.target = std::string(target); |
| 278 | 287 |
| 279 if (len) { | 288 if (len) { |
| 280 params.buffer.resize(len); | 289 params.buffer.resize(len); |
| 281 memcpy(¶ms.buffer.front(), buf, len); | 290 memcpy(¶ms.buffer.front(), buf, len); |
| 282 } | 291 } |
| 283 | 292 |
| 284 params.is_file_data = is_file_data; | 293 params.is_file_data = is_file_data; |
| 285 params.notify = notify; | 294 params.notify = notify; |
| 286 params.url = url; | 295 params.url = url; |
| 287 params.notify_data = notify_data; | 296 params.notify_data = notify_data; |
| 288 params.popups_allowed = popups_allowed; | 297 params.popups_allowed = popups_allowed; |
| 289 | 298 |
| 290 Send(new PluginHostMsg_URLRequest(route_id_, params)); | 299 Send(new PluginHostMsg_URLRequest(route_id_, params)); |
| 291 } | 300 } |
| 292 | 301 |
| 293 void WebPluginProxy::Paint(const gfx::Rect& rect) { | 302 void WebPluginProxy::Paint(const gfx::Rect& rect) { |
| 303 #if defined(OS_WIN) |
| 294 if (!windowless_hdc_) | 304 if (!windowless_hdc_) |
| 295 return; | 305 return; |
| 296 | 306 |
| 297 // Clear the damaged area so that if the plugin doesn't paint there we won't | 307 // Clear the damaged area so that if the plugin doesn't paint there we won't |
| 298 // end up with the old values. | 308 // end up with the old values. |
| 299 gfx::Rect offset_rect = rect; | 309 gfx::Rect offset_rect = rect; |
| 300 offset_rect.Offset(delegate_->GetRect().origin()); | 310 offset_rect.Offset(delegate_->GetRect().origin()); |
| 301 if (!background_hdc_) { | 311 if (!background_hdc_) { |
| 302 FillRect(windowless_hdc_, &offset_rect.ToRECT(), | 312 FillRect(windowless_hdc_, &offset_rect.ToRECT(), |
| 303 static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH))); | 313 static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH))); |
| 304 } else { | 314 } else { |
| 305 BitBlt(windowless_hdc_, offset_rect.x(), offset_rect.y(), | 315 BitBlt(windowless_hdc_, offset_rect.x(), offset_rect.y(), |
| 306 offset_rect.width(), offset_rect.height(), background_hdc_, | 316 offset_rect.width(), offset_rect.height(), background_hdc_, |
| 307 rect.x(), rect.y(), SRCCOPY); | 317 rect.x(), rect.y(), SRCCOPY); |
| 308 } | 318 } |
| 309 | 319 |
| 310 RECT clip_rect = rect.ToRECT(); | 320 RECT clip_rect = rect.ToRECT(); |
| 311 HRGN clip_region = CreateRectRgnIndirect(&clip_rect); | 321 HRGN clip_region = CreateRectRgnIndirect(&clip_rect); |
| 312 SelectClipRgn(windowless_hdc_, clip_region); | 322 SelectClipRgn(windowless_hdc_, clip_region); |
| 313 | 323 |
| 314 // Before we send the invalidate, paint so that renderer uses the updated | 324 // Before we send the invalidate, paint so that renderer uses the updated |
| 315 // bitmap. | 325 // bitmap. |
| 316 delegate_->Paint(windowless_hdc_, offset_rect); | 326 delegate_->Paint(windowless_hdc_, offset_rect); |
| 317 | 327 |
| 318 SelectClipRgn(windowless_hdc_, NULL); | 328 SelectClipRgn(windowless_hdc_, NULL); |
| 319 DeleteObject(clip_region); | 329 DeleteObject(clip_region); |
| 330 #else |
| 331 // TODO(port): windowless painting. |
| 332 NOTIMPLEMENTED(); |
| 333 #endif |
| 320 } | 334 } |
| 321 | 335 |
| 322 void WebPluginProxy::UpdateGeometry( | 336 void WebPluginProxy::UpdateGeometry( |
| 323 const gfx::Rect& window_rect, | 337 const gfx::Rect& window_rect, |
| 324 const gfx::Rect& clip_rect, | 338 const gfx::Rect& clip_rect, |
| 325 const base::SharedMemoryHandle& windowless_buffer, | 339 const TransportDIB::Id& windowless_buffer_id, |
| 326 const base::SharedMemoryHandle& background_buffer) { | 340 const TransportDIB::Id& background_buffer_id) { |
| 341 #if defined(OS_WIN) |
| 342 // TODO(port): this isn't correct usage of a TransportDIB; for now, |
| 343 // the caller temporarly just stuffs the handle into the HANDLE |
| 344 // field of the TransportDIB::Id so it should behave like the older |
| 345 // code. |
| 327 gfx::Rect old = delegate_->GetRect(); | 346 gfx::Rect old = delegate_->GetRect(); |
| 328 gfx::Rect old_clip_rect = delegate_->GetClipRect(); | 347 gfx::Rect old_clip_rect = delegate_->GetClipRect(); |
| 329 | 348 |
| 330 bool moved = old.x() != window_rect.x() || old.y() != window_rect.y(); | 349 bool moved = old.x() != window_rect.x() || old.y() != window_rect.y(); |
| 331 delegate_->UpdateGeometry(window_rect, clip_rect); | 350 delegate_->UpdateGeometry(window_rect, clip_rect); |
| 332 if (windowless_buffer) { | 351 if (windowless_buffer_id.handle) { |
| 333 // The plugin's rect changed, so now we have a new buffer to draw into. | 352 // The plugin's rect changed, so now we have a new buffer to draw into. |
| 334 SetWindowlessBuffer(windowless_buffer, background_buffer); | 353 SetWindowlessBuffer(windowless_buffer_id.handle, |
| 354 background_buffer_id.handle); |
| 335 } else if (moved) { | 355 } else if (moved) { |
| 336 // The plugin moved, so update our world transform. | 356 // The plugin moved, so update our world transform. |
| 337 UpdateTransform(); | 357 UpdateTransform(); |
| 338 } | 358 } |
| 339 // Send over any pending invalidates which occured when the plugin was | 359 // Send over any pending invalidates which occured when the plugin was |
| 340 // off screen. | 360 // off screen. |
| 341 if (delegate_->IsWindowless() && !clip_rect.IsEmpty() && | 361 if (delegate_->IsWindowless() && !clip_rect.IsEmpty() && |
| 342 old_clip_rect.IsEmpty() && !damaged_rect_.IsEmpty()) { | 362 old_clip_rect.IsEmpty() && !damaged_rect_.IsEmpty()) { |
| 343 InvalidateRect(damaged_rect_); | 363 InvalidateRect(damaged_rect_); |
| 344 } | 364 } |
| 365 #else |
| 366 NOTIMPLEMENTED(); |
| 367 #endif |
| 345 } | 368 } |
| 346 | 369 |
| 370 #if defined(OS_WIN) |
| 347 void WebPluginProxy::SetWindowlessBuffer( | 371 void WebPluginProxy::SetWindowlessBuffer( |
| 348 const base::SharedMemoryHandle& windowless_buffer, | 372 const base::SharedMemoryHandle& windowless_buffer, |
| 349 const base::SharedMemoryHandle& background_buffer) { | 373 const base::SharedMemoryHandle& background_buffer) { |
| 350 // Convert the shared memory handle to a handle that works in our process, | 374 // Convert the shared memory handle to a handle that works in our process, |
| 351 // and then use that to create an HDC. | 375 // and then use that to create an HDC. |
| 352 ConvertBuffer(windowless_buffer, | 376 ConvertBuffer(windowless_buffer, |
| 353 &windowless_shared_section_, | 377 &windowless_shared_section_, |
| 354 &windowless_bitmap_, | 378 &windowless_bitmap_, |
| 355 &windowless_hdc_); | 379 &windowless_hdc_); |
| 356 if (background_buffer) { | 380 if (background_buffer) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 | 428 |
| 405 XFORM xf; | 429 XFORM xf; |
| 406 xf.eDx = static_cast<FLOAT>(-delegate_->GetRect().x()); | 430 xf.eDx = static_cast<FLOAT>(-delegate_->GetRect().x()); |
| 407 xf.eDy = static_cast<FLOAT>(-delegate_->GetRect().y()); | 431 xf.eDy = static_cast<FLOAT>(-delegate_->GetRect().y()); |
| 408 xf.eM11 = 1; | 432 xf.eM11 = 1; |
| 409 xf.eM21 = 0; | 433 xf.eM21 = 0; |
| 410 xf.eM12 = 0; | 434 xf.eM12 = 0; |
| 411 xf.eM22 = 1; | 435 xf.eM22 = 1; |
| 412 SetWorldTransform(windowless_hdc_, &xf); | 436 SetWorldTransform(windowless_hdc_, &xf); |
| 413 } | 437 } |
| 438 #endif |
| 414 | 439 |
| 415 void WebPluginProxy::CancelDocumentLoad() { | 440 void WebPluginProxy::CancelDocumentLoad() { |
| 416 Send(new PluginHostMsg_CancelDocumentLoad(route_id_)); | 441 Send(new PluginHostMsg_CancelDocumentLoad(route_id_)); |
| 417 } | 442 } |
| 418 | 443 |
| 419 void WebPluginProxy::InitiateHTTPRangeRequest(const char* url, | 444 void WebPluginProxy::InitiateHTTPRangeRequest(const char* url, |
| 420 const char* range_info, | 445 const char* range_info, |
| 421 intptr_t existing_stream, | 446 intptr_t existing_stream, |
| 422 bool notify_needed, | 447 bool notify_needed, |
| 423 intptr_t notify_data) { | 448 intptr_t notify_data) { |
| 424 | 449 |
| 425 Send(new PluginHostMsg_InitiateHTTPRangeRequest(route_id_, url, | 450 Send(new PluginHostMsg_InitiateHTTPRangeRequest(route_id_, url, |
| 426 range_info, existing_stream, | 451 range_info, existing_stream, |
| 427 notify_needed, notify_data)); | 452 notify_needed, notify_data)); |
| 428 } | 453 } |
| 429 | 454 |
| 430 void WebPluginProxy::OnPaint(const gfx::Rect& damaged_rect) { | 455 void WebPluginProxy::OnPaint(const gfx::Rect& damaged_rect) { |
| 431 Paint(damaged_rect); | 456 Paint(damaged_rect); |
| 432 Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect)); | 457 Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect)); |
| 433 } | 458 } |
| 434 | 459 |
| 435 bool WebPluginProxy::IsOffTheRecord() { | 460 bool WebPluginProxy::IsOffTheRecord() { |
| 436 return channel_->off_the_record(); | 461 return channel_->off_the_record(); |
| 437 } | 462 } |
| OLD | NEW |