| 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 "chrome/common/gfx/chrome_canvas.h" | 11 #include "chrome/common/gfx/chrome_canvas.h" |
| 12 #include "chrome/common/plugin_messages.h" | 12 #include "chrome/common/plugin_messages.h" |
| 13 #include "chrome/common/win_util.h" | 13 #include "chrome/common/win_util.h" |
| 14 #include "chrome/plugin/plugin_channel.h" | |
| 15 #include "chrome/plugin/webplugin_delegate_stub.h" | |
| 16 #include "chrome/plugin/npobject_proxy.h" | 14 #include "chrome/plugin/npobject_proxy.h" |
| 17 #include "chrome/plugin/npobject_util.h" | 15 #include "chrome/plugin/npobject_util.h" |
| 16 #include "chrome/plugin/plugin_channel.h" |
| 17 #include "chrome/plugin/plugin_thread.h" |
| 18 #include "chrome/plugin/webplugin_delegate_stub.h" |
| 18 #include "skia/ext/platform_device.h" | 19 #include "skia/ext/platform_device.h" |
| 19 #include "webkit/glue/plugins/webplugin_delegate_impl.h" | 20 #include "webkit/glue/plugins/webplugin_delegate_impl.h" |
| 20 | 21 |
| 21 typedef std::map<CPBrowsingContext, WebPluginProxy*> ContextMap; | 22 typedef std::map<CPBrowsingContext, WebPluginProxy*> ContextMap; |
| 22 static ContextMap& GetContextMap() { | 23 static ContextMap& GetContextMap() { |
| 23 return *Singleton<ContextMap>::get(); | 24 return *Singleton<ContextMap>::get(); |
| 24 } | 25 } |
| 25 | 26 |
| 26 WebPluginProxy::WebPluginProxy( | 27 WebPluginProxy::WebPluginProxy( |
| 27 PluginChannel* channel, | 28 PluginChannel* channel, |
| 28 int route_id, | 29 int route_id, |
| 29 WebPluginDelegateImpl* delegate, | 30 WebPluginDelegateImpl* delegate, |
| 30 HANDLE modal_dialog_event) | 31 HANDLE modal_dialog_event) |
| 31 : channel_(channel), | 32 : channel_(channel), |
| 32 route_id_(route_id), | 33 route_id_(route_id), |
| 33 cp_browsing_context_(0), | 34 cp_browsing_context_(0), |
| 34 window_npobject_(NULL), | 35 window_npobject_(NULL), |
| 35 plugin_element_(NULL), | 36 plugin_element_(NULL), |
| 36 delegate_(delegate), | 37 delegate_(delegate), |
| 37 waiting_for_paint_(false), | 38 waiting_for_paint_(false), |
| 38 #pragma warning(suppress: 4355) // can use this | 39 #pragma warning(suppress: 4355) // can use this |
| 39 runnable_method_factory_(this) { | 40 runnable_method_factory_(this), |
| 41 parent_window_(NULL) { |
| 40 | 42 |
| 41 HANDLE event; | 43 HANDLE event; |
| 42 BOOL result = DuplicateHandle(channel->renderer_handle(), | 44 BOOL result = DuplicateHandle(channel->renderer_handle(), |
| 43 modal_dialog_event, | 45 modal_dialog_event, |
| 44 GetCurrentProcess(), | 46 GetCurrentProcess(), |
| 45 &event, | 47 &event, |
| 46 SYNCHRONIZE, | 48 SYNCHRONIZE, |
| 47 FALSE, | 49 FALSE, |
| 48 0); | 50 0); |
| 49 DCHECK(result) << "Couldn't duplicate the modal dialog handle for the plugin."
; | 51 DCHECK(result) << "Couldn't duplicate the modal dialog handle for the plugin."
; |
| 50 modal_dialog_event_.Set(event); | 52 modal_dialog_event_.Set(event); |
| 51 } | 53 } |
| 52 | 54 |
| 53 WebPluginProxy::~WebPluginProxy() { | 55 WebPluginProxy::~WebPluginProxy() { |
| 54 if (cp_browsing_context_) | 56 if (cp_browsing_context_) |
| 55 GetContextMap().erase(cp_browsing_context_); | 57 GetContextMap().erase(cp_browsing_context_); |
| 58 |
| 59 if (parent_window_) { |
| 60 PluginThread::GetPluginThread()->Send( |
| 61 new PluginProcessHostMsg_DestroyWindow(parent_window_)); |
| 62 } |
| 56 } | 63 } |
| 57 | 64 |
| 58 bool WebPluginProxy::Send(IPC::Message* msg) { | 65 bool WebPluginProxy::Send(IPC::Message* msg) { |
| 59 return channel_->Send(msg); | 66 return channel_->Send(msg); |
| 60 } | 67 } |
| 61 | 68 |
| 62 void WebPluginProxy::SetWindow(HWND window, HANDLE pump_messages_event) { | 69 void WebPluginProxy::SetWindow(HWND window, HANDLE pump_messages_event) { |
| 63 HANDLE pump_messages_event_for_renderer = NULL; | 70 HANDLE pump_messages_event_for_renderer = NULL; |
| 64 | 71 |
| 65 if (pump_messages_event) { | 72 if (pump_messages_event) { |
| 66 DCHECK(window == NULL); | 73 DCHECK(window == NULL); |
| 67 DuplicateHandle(GetCurrentProcess(), pump_messages_event, | 74 DuplicateHandle(GetCurrentProcess(), pump_messages_event, |
| 68 channel_->renderer_handle(), | 75 channel_->renderer_handle(), |
| 69 &pump_messages_event_for_renderer, | 76 &pump_messages_event_for_renderer, |
| 70 0, FALSE, DUPLICATE_SAME_ACCESS); | 77 0, FALSE, DUPLICATE_SAME_ACCESS); |
| 71 DCHECK(pump_messages_event_for_renderer != NULL); | 78 DCHECK(pump_messages_event_for_renderer != NULL); |
| 79 } else { |
| 80 DCHECK (window); |
| 81 // To make scrolling windowed plugins fast, we create the page's direct |
| 82 // child windows in the browser process. This way no cross process messages |
| 83 // are sent. |
| 84 HWND old_parent = GetParent(window); |
| 85 IPC::SyncMessage* msg = new PluginProcessHostMsg_CreateWindow( |
| 86 old_parent, &parent_window_); |
| 87 |
| 88 // Need to process window messages in the meantime to avoid a deadlock if |
| 89 // the browser paints or sends any other (synchronous) WM_ message to the |
| 90 // plugin window. |
| 91 msg->EnableMessagePumping(); |
| 92 PluginThread::GetPluginThread()->Send(msg); |
| 93 |
| 94 SetParent(window, parent_window_); |
| 95 |
| 96 // We want the browser process to move this window which has a message loop |
| 97 // in its process. |
| 98 window = parent_window_; |
| 72 } | 99 } |
| 73 | 100 |
| 74 Send(new PluginHostMsg_SetWindow(route_id_, window, | 101 Send(new PluginHostMsg_SetWindow(route_id_, window, |
| 75 pump_messages_event_for_renderer)); | 102 pump_messages_event_for_renderer)); |
| 76 } | 103 } |
| 77 | 104 |
| 78 void WebPluginProxy::CancelResource(int id) { | 105 void WebPluginProxy::CancelResource(int id) { |
| 79 Send(new PluginHostMsg_CancelResource(route_id_, id)); | 106 Send(new PluginHostMsg_CancelResource(route_id_, id)); |
| 80 resource_clients_.erase(id); | 107 resource_clients_.erase(id); |
| 81 } | 108 } |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 } | 300 } |
| 274 | 301 |
| 275 // Before we send the invalidate, paint so that renderer uses the updated | 302 // Before we send the invalidate, paint so that renderer uses the updated |
| 276 // bitmap. | 303 // bitmap. |
| 277 delegate_->Paint(windowless_hdc_, offset_rect); | 304 delegate_->Paint(windowless_hdc_, offset_rect); |
| 278 } | 305 } |
| 279 | 306 |
| 280 void WebPluginProxy::UpdateGeometry( | 307 void WebPluginProxy::UpdateGeometry( |
| 281 const gfx::Rect& window_rect, | 308 const gfx::Rect& window_rect, |
| 282 const gfx::Rect& clip_rect, | 309 const gfx::Rect& clip_rect, |
| 283 const std::vector<gfx::Rect>& cutout_rects, | |
| 284 bool visible, | |
| 285 const base::SharedMemoryHandle& windowless_buffer, | 310 const base::SharedMemoryHandle& windowless_buffer, |
| 286 const base::SharedMemoryHandle& background_buffer) { | 311 const base::SharedMemoryHandle& background_buffer) { |
| 287 gfx::Rect old = delegate_->rect(); | 312 gfx::Rect old = delegate_->rect(); |
| 288 gfx::Rect old_clip_rect = delegate_->clip_rect(); | 313 gfx::Rect old_clip_rect = delegate_->clip_rect(); |
| 289 | 314 |
| 290 bool moved = delegate_->rect().x() != window_rect.x() || | 315 bool moved = delegate_->rect().x() != window_rect.x() || |
| 291 delegate_->rect().y() != window_rect.y(); | 316 delegate_->rect().y() != window_rect.y(); |
| 292 delegate_->UpdateGeometry(window_rect, clip_rect, cutout_rects, visible); | 317 delegate_->UpdateGeometry(window_rect, clip_rect); |
| 293 if (windowless_buffer) { | 318 if (windowless_buffer) { |
| 294 // The plugin's rect changed, so now we have a new buffer to draw into. | 319 // The plugin's rect changed, so now we have a new buffer to draw into. |
| 295 SetWindowlessBuffer(windowless_buffer, background_buffer); | 320 SetWindowlessBuffer(windowless_buffer, background_buffer); |
| 296 } else if (moved) { | 321 } else if (moved) { |
| 297 // The plugin moved, so update our world transform. | 322 // The plugin moved, so update our world transform. |
| 298 UpdateTransform(); | 323 UpdateTransform(); |
| 299 } | 324 } |
| 300 // Send over any pending invalidates which occured when the plugin was | 325 // Send over any pending invalidates which occured when the plugin was |
| 301 // off screen. | 326 // off screen. |
| 302 if (visible && delegate_->windowless() && !clip_rect.IsEmpty() && | 327 if (delegate_->windowless() && !clip_rect.IsEmpty() && |
| 303 old_clip_rect.IsEmpty() && !damaged_rect_.IsEmpty()) { | 328 old_clip_rect.IsEmpty() && !damaged_rect_.IsEmpty()) { |
| 304 InvalidateRect(damaged_rect_); | 329 InvalidateRect(damaged_rect_); |
| 305 } | 330 } |
| 306 } | 331 } |
| 307 | 332 |
| 308 void WebPluginProxy::SetWindowlessBuffer( | 333 void WebPluginProxy::SetWindowlessBuffer( |
| 309 const base::SharedMemoryHandle& windowless_buffer, | 334 const base::SharedMemoryHandle& windowless_buffer, |
| 310 const base::SharedMemoryHandle& background_buffer) { | 335 const base::SharedMemoryHandle& background_buffer) { |
| 311 // Convert the shared memory handle to a handle that works in our process, | 336 // Convert the shared memory handle to a handle that works in our process, |
| 312 // and then use that to create an HDC. | 337 // and then use that to create an HDC. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 | 410 |
| 386 Send(new PluginHostMsg_InitiateHTTPRangeRequest(route_id_, url, | 411 Send(new PluginHostMsg_InitiateHTTPRangeRequest(route_id_, url, |
| 387 range_info, existing_stream, | 412 range_info, existing_stream, |
| 388 notify_needed, notify_data)); | 413 notify_needed, notify_data)); |
| 389 } | 414 } |
| 390 | 415 |
| 391 void WebPluginProxy::OnPaint(const gfx::Rect& damaged_rect) { | 416 void WebPluginProxy::OnPaint(const gfx::Rect& damaged_rect) { |
| 392 Paint(damaged_rect); | 417 Paint(damaged_rect); |
| 393 Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect)); | 418 Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect)); |
| 394 } | 419 } |
| OLD | NEW |