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 |