OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/plugin/webplugin_proxy.h" | |
6 | |
7 #include "build/build_config.h" | |
8 | |
9 #include "base/lazy_instance.h" | |
10 #include "base/scoped_handle.h" | |
11 #include "base/shared_memory.h" | |
12 #include "build/build_config.h" | |
13 #include "chrome/plugin/npobject_proxy.h" | |
14 #include "chrome/plugin/npobject_util.h" | |
15 #include "chrome/plugin/plugin_channel.h" | |
16 #include "chrome/plugin/plugin_thread.h" | |
17 #include "content/common/content_client.h" | |
18 #include "content/common/plugin_messages.h" | |
19 #include "skia/ext/platform_device.h" | |
20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" | |
21 #include "ui/gfx/blit.h" | |
22 #include "ui/gfx/canvas.h" | |
23 #include "webkit/plugins/npapi/webplugin_delegate_impl.h" | |
24 | |
25 #if defined(OS_MACOSX) | |
26 #include "base/mac/mac_util.h" | |
27 #include "base/mac/scoped_cftyperef.h" | |
28 #include "chrome/plugin/webplugin_accelerated_surface_proxy_mac.h" | |
29 #endif | |
30 | |
31 #if defined(OS_WIN) | |
32 #include "content/common/section_util_win.h" | |
33 #include "ui/gfx/gdi_util.h" | |
34 #endif | |
35 | |
36 #if defined(USE_X11) | |
37 #include "ui/base/x/x11_util_internal.h" | |
38 #endif | |
39 | |
40 using WebKit::WebBindings; | |
41 | |
42 using webkit::npapi::WebPluginResourceClient; | |
43 #if defined(OS_MACOSX) | |
44 using webkit::npapi::WebPluginAcceleratedSurface; | |
45 #endif | |
46 | |
47 WebPluginProxy::WebPluginProxy( | |
48 PluginChannel* channel, | |
49 int route_id, | |
50 const GURL& page_url, | |
51 gfx::NativeViewId containing_window, | |
52 int host_render_view_routing_id) | |
53 : channel_(channel), | |
54 route_id_(route_id), | |
55 window_npobject_(NULL), | |
56 plugin_element_(NULL), | |
57 delegate_(NULL), | |
58 waiting_for_paint_(false), | |
59 containing_window_(containing_window), | |
60 page_url_(page_url), | |
61 transparent_(false), | |
62 host_render_view_routing_id_(host_render_view_routing_id), | |
63 ALLOW_THIS_IN_INITIALIZER_LIST(runnable_method_factory_(this)) { | |
64 #if defined(USE_X11) | |
65 windowless_shm_pixmap_ = None; | |
66 use_shm_pixmap_ = false; | |
67 | |
68 // If the X server supports SHM pixmaps | |
69 // and the color depth and masks match, | |
70 // then consider using SHM pixmaps for windowless plugin painting. | |
71 Display* display = ui::GetXDisplay(); | |
72 if (ui::QuerySharedMemorySupport(display) == ui::SHARED_MEMORY_PIXMAP && | |
73 ui::BitsPerPixelForPixmapDepth( | |
74 display, DefaultDepth(display, 0)) == 32) { | |
75 Visual* vis = DefaultVisual(display, 0); | |
76 | |
77 if (vis->red_mask == 0xff0000 && | |
78 vis->green_mask == 0xff00 && | |
79 vis->blue_mask == 0xff) | |
80 use_shm_pixmap_ = true; | |
81 } | |
82 #endif | |
83 } | |
84 | |
85 WebPluginProxy::~WebPluginProxy() { | |
86 #if defined(USE_X11) | |
87 if (windowless_shm_pixmap_ != None) | |
88 XFreePixmap(ui::GetXDisplay(), windowless_shm_pixmap_); | |
89 #endif | |
90 | |
91 #if defined(OS_MACOSX) | |
92 // Destroy the surface early, since it may send messages during cleanup. | |
93 if (accelerated_surface_.get()) | |
94 accelerated_surface_.reset(); | |
95 #endif | |
96 } | |
97 | |
98 bool WebPluginProxy::Send(IPC::Message* msg) { | |
99 return channel_->Send(msg); | |
100 } | |
101 | |
102 void WebPluginProxy::SetWindow(gfx::PluginWindowHandle window) { | |
103 Send(new PluginHostMsg_SetWindow(route_id_, window)); | |
104 } | |
105 | |
106 void WebPluginProxy::SetAcceptsInputEvents(bool accepts) { | |
107 NOTREACHED(); | |
108 } | |
109 | |
110 void WebPluginProxy::WillDestroyWindow(gfx::PluginWindowHandle window) { | |
111 #if defined(OS_WIN) | |
112 PluginThread::current()->Send( | |
113 new PluginProcessHostMsg_PluginWindowDestroyed( | |
114 window, ::GetParent(window))); | |
115 #elif defined(USE_X11) | |
116 // Nothing to do. | |
117 #else | |
118 NOTIMPLEMENTED(); | |
119 #endif | |
120 } | |
121 | |
122 #if defined(OS_WIN) | |
123 void WebPluginProxy::SetWindowlessPumpEvent(HANDLE pump_messages_event) { | |
124 HANDLE pump_messages_event_for_renderer = NULL; | |
125 DuplicateHandle(GetCurrentProcess(), pump_messages_event, | |
126 channel_->renderer_handle(), | |
127 &pump_messages_event_for_renderer, | |
128 0, FALSE, DUPLICATE_SAME_ACCESS); | |
129 DCHECK(pump_messages_event_for_renderer != NULL); | |
130 Send(new PluginHostMsg_SetWindowlessPumpEvent( | |
131 route_id_, pump_messages_event_for_renderer)); | |
132 } | |
133 #endif | |
134 | |
135 void WebPluginProxy::CancelResource(unsigned long id) { | |
136 Send(new PluginHostMsg_CancelResource(route_id_, id)); | |
137 resource_clients_.erase(id); | |
138 } | |
139 | |
140 void WebPluginProxy::Invalidate() { | |
141 gfx::Rect rect(0, 0, | |
142 delegate_->GetRect().width(), | |
143 delegate_->GetRect().height()); | |
144 InvalidateRect(rect); | |
145 } | |
146 | |
147 void WebPluginProxy::InvalidateRect(const gfx::Rect& rect) { | |
148 #if defined(OS_MACOSX) | |
149 // If this is a Core Animation plugin, all we need to do is inform the | |
150 // delegate. | |
151 if (!windowless_context_.get()) { | |
152 delegate_->PluginDidInvalidate(); | |
153 return; | |
154 } | |
155 | |
156 // Some plugins will send invalidates larger than their own rect when | |
157 // offscreen, so constrain invalidates to the plugin rect. | |
158 gfx::Rect plugin_rect = delegate_->GetRect(); | |
159 plugin_rect.set_origin(gfx::Point(0, 0)); | |
160 const gfx::Rect invalidate_rect(rect.Intersect(plugin_rect)); | |
161 #else | |
162 const gfx::Rect invalidate_rect(rect); | |
163 #endif | |
164 damaged_rect_ = damaged_rect_.Union(invalidate_rect); | |
165 // Ignore NPN_InvalidateRect calls with empty rects. Also don't send an | |
166 // invalidate if it's outside the clipping region, since if we did it won't | |
167 // lead to a paint and we'll be stuck waiting forever for a DidPaint response. | |
168 // | |
169 // TODO(piman): There is a race condition here, because this test assumes | |
170 // that when the paint actually occurs, the clip rect will not have changed. | |
171 // This is not true because scrolling (or window resize) could occur and be | |
172 // handled by the renderer before it receives the InvalidateRect message, | |
173 // changing the clip rect and then not painting. | |
174 if (damaged_rect_.IsEmpty() || | |
175 !delegate_->GetClipRect().Intersects(damaged_rect_)) | |
176 return; | |
177 | |
178 // Only send a single InvalidateRect message at a time. From DidPaint we | |
179 // will dispatch an additional InvalidateRect message if necessary. | |
180 if (!waiting_for_paint_) { | |
181 waiting_for_paint_ = true; | |
182 // Invalidates caused by calls to NPN_InvalidateRect/NPN_InvalidateRgn | |
183 // need to be painted asynchronously as per the NPAPI spec. | |
184 MessageLoop::current()->PostTask(FROM_HERE, | |
185 runnable_method_factory_.NewRunnableMethod( | |
186 &WebPluginProxy::OnPaint, damaged_rect_)); | |
187 damaged_rect_ = gfx::Rect(); | |
188 } | |
189 } | |
190 | |
191 NPObject* WebPluginProxy::GetWindowScriptNPObject() { | |
192 if (window_npobject_) | |
193 return WebBindings::retainObject(window_npobject_); | |
194 | |
195 int npobject_route_id = channel_->GenerateRouteID(); | |
196 bool success = false; | |
197 Send(new PluginHostMsg_GetWindowScriptNPObject( | |
198 route_id_, npobject_route_id, &success)); | |
199 if (!success) | |
200 return NULL; | |
201 | |
202 window_npobject_ = NPObjectProxy::Create( | |
203 channel_, npobject_route_id, containing_window_, page_url_); | |
204 | |
205 return window_npobject_; | |
206 } | |
207 | |
208 NPObject* WebPluginProxy::GetPluginElement() { | |
209 if (plugin_element_) | |
210 return WebBindings::retainObject(plugin_element_); | |
211 | |
212 int npobject_route_id = channel_->GenerateRouteID(); | |
213 bool success = false; | |
214 Send(new PluginHostMsg_GetPluginElement(route_id_, npobject_route_id, | |
215 &success)); | |
216 if (!success) | |
217 return NULL; | |
218 | |
219 plugin_element_ = NPObjectProxy::Create( | |
220 channel_, npobject_route_id, containing_window_, page_url_); | |
221 | |
222 return plugin_element_; | |
223 } | |
224 | |
225 void WebPluginProxy::SetCookie(const GURL& url, | |
226 const GURL& first_party_for_cookies, | |
227 const std::string& cookie) { | |
228 Send(new PluginHostMsg_SetCookie(route_id_, url, | |
229 first_party_for_cookies, cookie)); | |
230 } | |
231 | |
232 std::string WebPluginProxy::GetCookies(const GURL& url, | |
233 const GURL& first_party_for_cookies) { | |
234 std::string cookies; | |
235 Send(new PluginHostMsg_GetCookies(route_id_, url, | |
236 first_party_for_cookies, &cookies)); | |
237 | |
238 return cookies; | |
239 } | |
240 | |
241 void WebPluginProxy::OnMissingPluginStatus(int status) { | |
242 Send(new PluginHostMsg_MissingPluginStatus(route_id_, status)); | |
243 } | |
244 | |
245 WebPluginResourceClient* WebPluginProxy::GetResourceClient(int id) { | |
246 ResourceClientMap::iterator iterator = resource_clients_.find(id); | |
247 // The IPC messages which deal with streams are now asynchronous. It is | |
248 // now possible to receive stream messages from the renderer for streams | |
249 // which may have been cancelled by the plugin. | |
250 if (iterator == resource_clients_.end()) { | |
251 return NULL; | |
252 } | |
253 | |
254 return iterator->second; | |
255 } | |
256 | |
257 int WebPluginProxy::GetRendererId() { | |
258 if (channel_.get()) | |
259 return channel_->renderer_id(); | |
260 return -1; | |
261 } | |
262 | |
263 void WebPluginProxy::DidPaint() { | |
264 // If we have an accumulated damaged rect, then check to see if we need to | |
265 // send out another InvalidateRect message. | |
266 waiting_for_paint_ = false; | |
267 if (!damaged_rect_.IsEmpty()) | |
268 InvalidateRect(damaged_rect_); | |
269 } | |
270 | |
271 void WebPluginProxy::OnResourceCreated(int resource_id, | |
272 WebPluginResourceClient* client) { | |
273 DCHECK(resource_clients_.find(resource_id) == resource_clients_.end()); | |
274 resource_clients_[resource_id] = client; | |
275 } | |
276 | |
277 void WebPluginProxy::HandleURLRequest(const char* url, | |
278 const char* method, | |
279 const char* target, | |
280 const char* buf, | |
281 unsigned int len, | |
282 int notify_id, | |
283 bool popups_allowed, | |
284 bool notify_redirects) { | |
285 if (!target && (0 == base::strcasecmp(method, "GET"))) { | |
286 // Please refer to https://bugzilla.mozilla.org/show_bug.cgi?id=366082 | |
287 // for more details on this. | |
288 if (delegate_->GetQuirks() & | |
289 webkit::npapi::WebPluginDelegateImpl:: | |
290 PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS) { | |
291 GURL request_url(url); | |
292 if (!request_url.SchemeIs("http") && | |
293 !request_url.SchemeIs("https") && | |
294 !request_url.SchemeIs("ftp")) { | |
295 return; | |
296 } | |
297 } | |
298 } | |
299 | |
300 PluginHostMsg_URLRequest_Params params; | |
301 params.url = url; | |
302 params.method = method; | |
303 if (target) | |
304 params.target = std::string(target); | |
305 | |
306 if (len) { | |
307 params.buffer.resize(len); | |
308 memcpy(¶ms.buffer.front(), buf, len); | |
309 } | |
310 | |
311 params.notify_id = notify_id; | |
312 params.popups_allowed = popups_allowed; | |
313 params.notify_redirects = notify_redirects; | |
314 | |
315 Send(new PluginHostMsg_URLRequest(route_id_, params)); | |
316 } | |
317 | |
318 void WebPluginProxy::Paint(const gfx::Rect& rect) { | |
319 #if defined(OS_MACOSX) | |
320 if (!windowless_context_.get()) | |
321 return; | |
322 #else | |
323 if (!windowless_canvas_.get()) | |
324 return; | |
325 #endif | |
326 | |
327 // Clear the damaged area so that if the plugin doesn't paint there we won't | |
328 // end up with the old values. | |
329 gfx::Rect offset_rect = rect; | |
330 offset_rect.Offset(delegate_->GetRect().origin()); | |
331 #if defined(OS_MACOSX) | |
332 CGContextSaveGState(windowless_context_); | |
333 // It is possible for windowless_context_ to change during plugin painting | |
334 // (since the plugin can make a synchronous call during paint event handling), | |
335 // in which case we don't want to try to restore it later. Not an owning ref | |
336 // since owning the ref without owning the shared backing memory doesn't make | |
337 // sense, so this should only be used for pointer comparisons. | |
338 CGContextRef saved_context_weak = windowless_context_.get(); | |
339 | |
340 if (background_context_.get()) { | |
341 base::mac::ScopedCFTypeRef<CGImageRef> image( | |
342 CGBitmapContextCreateImage(background_context_)); | |
343 CGRect source_rect = rect.ToCGRect(); | |
344 // Flip the rect we use to pull from the canvas, since it's upside-down. | |
345 source_rect.origin.y = CGImageGetHeight(image) - rect.y() - rect.height(); | |
346 base::mac::ScopedCFTypeRef<CGImageRef> sub_image( | |
347 CGImageCreateWithImageInRect(image, source_rect)); | |
348 CGContextDrawImage(windowless_context_, rect.ToCGRect(), sub_image); | |
349 } else if (transparent_) { | |
350 CGContextClearRect(windowless_context_, rect.ToCGRect()); | |
351 } | |
352 CGContextClipToRect(windowless_context_, rect.ToCGRect()); | |
353 delegate_->Paint(windowless_context_, rect); | |
354 if (windowless_context_.get() == saved_context_weak) | |
355 CGContextRestoreGState(windowless_context_); | |
356 #else | |
357 windowless_canvas_->save(); | |
358 | |
359 // The given clip rect is relative to the plugin coordinate system. | |
360 SkRect sk_rect = { SkIntToScalar(rect.x()), | |
361 SkIntToScalar(rect.y()), | |
362 SkIntToScalar(rect.right()), | |
363 SkIntToScalar(rect.bottom()) }; | |
364 windowless_canvas_->clipRect(sk_rect); | |
365 | |
366 // Setup the background. | |
367 if (background_canvas_.get()) { | |
368 // When a background canvas is given, we're in transparent mode. This means | |
369 // the plugin wants to have the image of the page in the canvas it's drawing | |
370 // into (which is windowless_canvas_) so it can do blending. So we copy the | |
371 // background bitmap into the windowless_canvas_. | |
372 const SkBitmap& background_bitmap = | |
373 background_canvas_->getTopPlatformDevice().accessBitmap(false); | |
374 windowless_canvas_->drawBitmap(background_bitmap, 0, 0); | |
375 } else { | |
376 // In non-transparent mode, the plugin doesn't care what's underneath, so we | |
377 // can just give it black. | |
378 SkPaint black_fill_paint; | |
379 black_fill_paint.setARGB(0xFF, 0x00, 0x00, 0x00); | |
380 windowless_canvas_->drawPaint(black_fill_paint); | |
381 } | |
382 | |
383 // Bring the windowless_canvas_ into the window coordinate system, which is | |
384 // how the plugin expects to draw (since the windowless API was originally | |
385 // designed just for scribbling over the web page). | |
386 windowless_canvas_->translate(SkIntToScalar(-delegate_->GetRect().x()), | |
387 SkIntToScalar(-delegate_->GetRect().y())); | |
388 | |
389 // Before we send the invalidate, paint so that renderer uses the updated | |
390 // bitmap. | |
391 delegate_->Paint(windowless_canvas_.get(), offset_rect); | |
392 | |
393 windowless_canvas_->restore(); | |
394 #endif | |
395 } | |
396 | |
397 void WebPluginProxy::UpdateGeometry( | |
398 const gfx::Rect& window_rect, | |
399 const gfx::Rect& clip_rect, | |
400 const TransportDIB::Handle& windowless_buffer, | |
401 const TransportDIB::Handle& background_buffer, | |
402 bool transparent | |
403 #if defined(OS_MACOSX) | |
404 , | |
405 int ack_key | |
406 #endif | |
407 ) { | |
408 gfx::Rect old = delegate_->GetRect(); | |
409 gfx::Rect old_clip_rect = delegate_->GetClipRect(); | |
410 transparent_ = transparent; | |
411 | |
412 // Update the buffers before doing anything that could call into plugin code, | |
413 // so that we don't process buffer changes out of order if plugins make | |
414 // synchronous calls that lead to nested UpdateGeometry calls. | |
415 if (TransportDIB::is_valid(windowless_buffer)) { | |
416 // The plugin's rect changed, so now we have a new buffer to draw into. | |
417 SetWindowlessBuffer(windowless_buffer, background_buffer, window_rect); | |
418 } | |
419 | |
420 #if defined(OS_MACOSX) | |
421 delegate_->UpdateGeometryAndContext(window_rect, clip_rect, | |
422 windowless_context_); | |
423 #else | |
424 delegate_->UpdateGeometry(window_rect, clip_rect); | |
425 #endif | |
426 | |
427 // Send over any pending invalidates which occured when the plugin was | |
428 // off screen. | |
429 if (delegate_->IsWindowless() && !clip_rect.IsEmpty() && | |
430 !damaged_rect_.IsEmpty()) { | |
431 InvalidateRect(damaged_rect_); | |
432 } | |
433 | |
434 #if defined(OS_MACOSX) | |
435 // The renderer is expecting an ACK message if ack_key is not -1. | |
436 if (ack_key != -1) { | |
437 Send(new PluginHostMsg_UpdateGeometry_ACK(route_id_, ack_key)); | |
438 } | |
439 #endif | |
440 } | |
441 | |
442 #if defined(OS_WIN) | |
443 void WebPluginProxy::SetWindowlessBuffer( | |
444 const TransportDIB::Handle& windowless_buffer, | |
445 const TransportDIB::Handle& background_buffer, | |
446 const gfx::Rect& window_rect) { | |
447 // Create a canvas that will reference the shared bits. We have to handle | |
448 // errors here since we're mapping a large amount of memory that may not fit | |
449 // in our address space, or go wrong in some other way. | |
450 windowless_canvas_.reset(new skia::PlatformCanvas); | |
451 if (!windowless_canvas_->initialize( | |
452 window_rect.width(), | |
453 window_rect.height(), | |
454 true, | |
455 chrome::GetSectionFromProcess(windowless_buffer, | |
456 channel_->renderer_handle(), false))) { | |
457 windowless_canvas_.reset(); | |
458 background_canvas_.reset(); | |
459 return; | |
460 } | |
461 | |
462 if (background_buffer) { | |
463 background_canvas_.reset(new skia::PlatformCanvas); | |
464 if (!background_canvas_->initialize( | |
465 window_rect.width(), | |
466 window_rect.height(), | |
467 true, | |
468 chrome::GetSectionFromProcess(background_buffer, | |
469 channel_->renderer_handle(), false))) { | |
470 windowless_canvas_.reset(); | |
471 background_canvas_.reset(); | |
472 return; | |
473 } | |
474 } | |
475 } | |
476 | |
477 #elif defined(OS_MACOSX) | |
478 | |
479 void WebPluginProxy::SetWindowlessBuffer( | |
480 const TransportDIB::Handle& windowless_buffer, | |
481 const TransportDIB::Handle& background_buffer, | |
482 const gfx::Rect& window_rect) { | |
483 // Convert the shared memory handle to a handle that works in our process, | |
484 // and then use that to create a CGContextRef. | |
485 windowless_dib_.reset(TransportDIB::Map(windowless_buffer)); | |
486 background_dib_.reset(TransportDIB::Map(background_buffer)); | |
487 windowless_context_.reset(CGBitmapContextCreate( | |
488 windowless_dib_->memory(), | |
489 window_rect.width(), | |
490 window_rect.height(), | |
491 8, 4 * window_rect.width(), | |
492 base::mac::GetSystemColorSpace(), | |
493 kCGImageAlphaPremultipliedFirst | | |
494 kCGBitmapByteOrder32Host)); | |
495 CGContextTranslateCTM(windowless_context_, 0, window_rect.height()); | |
496 CGContextScaleCTM(windowless_context_, 1, -1); | |
497 if (background_dib_.get()) { | |
498 background_context_.reset(CGBitmapContextCreate( | |
499 background_dib_->memory(), | |
500 window_rect.width(), | |
501 window_rect.height(), | |
502 8, 4 * window_rect.width(), | |
503 base::mac::GetSystemColorSpace(), | |
504 kCGImageAlphaPremultipliedFirst | | |
505 kCGBitmapByteOrder32Host)); | |
506 CGContextTranslateCTM(background_context_, 0, window_rect.height()); | |
507 CGContextScaleCTM(background_context_, 1, -1); | |
508 } | |
509 } | |
510 | |
511 #elif defined(USE_X11) | |
512 | |
513 void WebPluginProxy::SetWindowlessBuffer( | |
514 const TransportDIB::Handle& windowless_buffer, | |
515 const TransportDIB::Handle& background_buffer, | |
516 const gfx::Rect& window_rect) { | |
517 int width = window_rect.width(); | |
518 int height = window_rect.height(); | |
519 windowless_dib_.reset(TransportDIB::Map(windowless_buffer)); | |
520 if (windowless_dib_.get()) { | |
521 windowless_canvas_.reset(windowless_dib_->GetPlatformCanvas(width, height)); | |
522 } else { | |
523 // This can happen if the renderer has already destroyed the TransportDIB | |
524 // by the time we receive the handle, e.g. in case of multiple resizes. | |
525 windowless_canvas_.reset(); | |
526 } | |
527 background_dib_.reset(TransportDIB::Map(background_buffer)); | |
528 if (background_dib_.get()) { | |
529 background_canvas_.reset(background_dib_->GetPlatformCanvas(width, height)); | |
530 } else { | |
531 background_canvas_.reset(); | |
532 } | |
533 | |
534 // If SHM pixmaps support is available, create a SHM pixmap and | |
535 // pass it to the delegate for windowless plugin painting. | |
536 if (delegate_->IsWindowless() && use_shm_pixmap_ && windowless_dib_.get()) { | |
537 Display* display = ui::GetXDisplay(); | |
538 XID root_window = ui::GetX11RootWindow(); | |
539 XShmSegmentInfo shminfo = {0}; | |
540 | |
541 if (windowless_shm_pixmap_ != None) | |
542 XFreePixmap(display, windowless_shm_pixmap_); | |
543 | |
544 shminfo.shmseg = windowless_dib_->MapToX(display); | |
545 // Create a shared memory pixmap based on the image buffer. | |
546 windowless_shm_pixmap_ = XShmCreatePixmap(display, root_window, | |
547 NULL, &shminfo, | |
548 width, height, | |
549 DefaultDepth(display, 0)); | |
550 | |
551 delegate_->SetWindowlessShmPixmap(windowless_shm_pixmap_); | |
552 } | |
553 } | |
554 | |
555 #endif | |
556 | |
557 void WebPluginProxy::CancelDocumentLoad() { | |
558 Send(new PluginHostMsg_CancelDocumentLoad(route_id_)); | |
559 } | |
560 | |
561 void WebPluginProxy::InitiateHTTPRangeRequest( | |
562 const char* url, const char* range_info, int range_request_id) { | |
563 Send(new PluginHostMsg_InitiateHTTPRangeRequest( | |
564 route_id_, url, range_info, range_request_id)); | |
565 } | |
566 | |
567 void WebPluginProxy::SetDeferResourceLoading(unsigned long resource_id, | |
568 bool defer) { | |
569 Send(new PluginHostMsg_DeferResourceLoading(route_id_, resource_id, defer)); | |
570 } | |
571 | |
572 #if defined(OS_MACOSX) | |
573 void WebPluginProxy::FocusChanged(bool focused) { | |
574 IPC::Message* msg = new PluginHostMsg_FocusChanged(route_id_, focused); | |
575 Send(msg); | |
576 } | |
577 | |
578 void WebPluginProxy::StartIme() { | |
579 IPC::Message* msg = new PluginHostMsg_StartIme(route_id_); | |
580 // This message can be sent during event-handling, and needs to be delivered | |
581 // within that context. | |
582 msg->set_unblock(true); | |
583 Send(msg); | |
584 } | |
585 | |
586 void WebPluginProxy::BindFakePluginWindowHandle(bool opaque) { | |
587 Send(new PluginHostMsg_BindFakePluginWindowHandle(route_id_, opaque)); | |
588 } | |
589 | |
590 WebPluginAcceleratedSurface* WebPluginProxy::GetAcceleratedSurface() { | |
591 if (!accelerated_surface_.get()) | |
592 accelerated_surface_.reset(new WebPluginAcceleratedSurfaceProxy(this)); | |
593 return accelerated_surface_.get(); | |
594 } | |
595 | |
596 void WebPluginProxy::AcceleratedFrameBuffersDidSwap( | |
597 gfx::PluginWindowHandle window, uint64 surface_id) { | |
598 Send(new PluginHostMsg_AcceleratedSurfaceBuffersSwapped( | |
599 route_id_, window, surface_id)); | |
600 } | |
601 | |
602 void WebPluginProxy::SetAcceleratedSurface( | |
603 gfx::PluginWindowHandle window, | |
604 const gfx::Size& size, | |
605 uint64 accelerated_surface_identifier) { | |
606 Send(new PluginHostMsg_AcceleratedSurfaceSetIOSurface( | |
607 route_id_, window, size.width(), size.height(), | |
608 accelerated_surface_identifier)); | |
609 } | |
610 | |
611 void WebPluginProxy::SetAcceleratedDIB( | |
612 gfx::PluginWindowHandle window, | |
613 const gfx::Size& size, | |
614 const TransportDIB::Handle& dib_handle) { | |
615 Send(new PluginHostMsg_AcceleratedSurfaceSetTransportDIB( | |
616 route_id_, window, size.width(), size.height(), dib_handle)); | |
617 } | |
618 | |
619 void WebPluginProxy::AllocSurfaceDIB(const size_t size, | |
620 TransportDIB::Handle* dib_handle) { | |
621 Send(new PluginHostMsg_AllocTransportDIB(route_id_, size, dib_handle)); | |
622 } | |
623 | |
624 void WebPluginProxy::FreeSurfaceDIB(TransportDIB::Id dib_id) { | |
625 Send(new PluginHostMsg_FreeTransportDIB(route_id_, dib_id)); | |
626 } | |
627 #endif | |
628 | |
629 void WebPluginProxy::OnPaint(const gfx::Rect& damaged_rect) { | |
630 content::GetContentClient()->SetActiveURL(page_url_); | |
631 | |
632 Paint(damaged_rect); | |
633 Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect)); | |
634 } | |
635 | |
636 bool WebPluginProxy::IsOffTheRecord() { | |
637 return channel_->incognito(); | |
638 } | |
639 | |
640 void WebPluginProxy::ResourceClientDeleted( | |
641 WebPluginResourceClient* resource_client) { | |
642 ResourceClientMap::iterator index = resource_clients_.begin(); | |
643 while (index != resource_clients_.end()) { | |
644 WebPluginResourceClient* client = (*index).second; | |
645 | |
646 if (client == resource_client) { | |
647 resource_clients_.erase(index++); | |
648 } else { | |
649 index++; | |
650 } | |
651 } | |
652 } | |
653 | |
654 void WebPluginProxy::URLRedirectResponse(bool allow, int resource_id) { | |
655 Send(new PluginHostMsg_URLRedirectResponse(route_id_, allow, resource_id)); | |
656 } | |
OLD | NEW |