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 |