| 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 "webkit/glue/plugins/webplugin_delegate_impl.h" | 5 #include "webkit/glue/plugins/webplugin_delegate_impl.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include <gtk/gtk.h> | 10 #include <gtk/gtk.h> |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 using WebKit::WebMouseEvent; | 37 using WebKit::WebMouseEvent; |
| 38 | 38 |
| 39 WebPluginDelegateImpl::WebPluginDelegateImpl( | 39 WebPluginDelegateImpl::WebPluginDelegateImpl( |
| 40 gfx::PluginWindowHandle containing_view, | 40 gfx::PluginWindowHandle containing_view, |
| 41 NPAPI::PluginInstance *instance) | 41 NPAPI::PluginInstance *instance) |
| 42 : windowed_handle_(0), | 42 : windowed_handle_(0), |
| 43 windowed_did_set_window_(false), | 43 windowed_did_set_window_(false), |
| 44 windowless_(false), | 44 windowless_(false), |
| 45 plugin_(NULL), | 45 plugin_(NULL), |
| 46 instance_(instance), | 46 instance_(instance), |
| 47 windowless_shm_pixmap_(None), |
| 47 pixmap_(NULL), | 48 pixmap_(NULL), |
| 48 first_event_time_(-1.0), | 49 first_event_time_(-1.0), |
| 49 plug_(NULL), | 50 plug_(NULL), |
| 50 socket_(NULL), | 51 socket_(NULL), |
| 51 parent_(containing_view), | 52 parent_(containing_view), |
| 52 quirks_(0), | 53 quirks_(0), |
| 53 handle_event_depth_(0), | 54 handle_event_depth_(0), |
| 54 first_set_window_call_(true) { | 55 first_set_window_call_(true) { |
| 55 memset(&window_, 0, sizeof(window_)); | 56 memset(&window_, 0, sizeof(window_)); |
| 56 if (instance_->mime_type() == "application/x-shockwave-flash") { | 57 if (instance_->mime_type() == "application/x-shockwave-flash") { |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 DCHECK_EQ(err, NPERR_NO_ERROR); | 393 DCHECK_EQ(err, NPERR_NO_ERROR); |
| 393 } | 394 } |
| 394 | 395 |
| 395 gfx::Rect pixmap_draw_rect = draw_rect; | 396 gfx::Rect pixmap_draw_rect = draw_rect; |
| 396 pixmap_draw_rect.Offset(offset_x, offset_y); | 397 pixmap_draw_rect.Offset(offset_x, offset_y); |
| 397 | 398 |
| 398 gfx::Rect pixmap_rect(0, 0, | 399 gfx::Rect pixmap_rect(0, 0, |
| 399 pixmap_draw_rect.right(), | 400 pixmap_draw_rect.right(), |
| 400 pixmap_draw_rect.bottom()); | 401 pixmap_draw_rect.bottom()); |
| 401 | 402 |
| 402 EnsurePixmapAtLeastSize(pixmap_rect.width(), pixmap_rect.height()); | |
| 403 | |
| 404 // Copy the current image into the pixmap, so the plugin can draw over | |
| 405 // this background. | |
| 406 cairo_t* cairo = gdk_cairo_create(pixmap_); | |
| 407 BlitContextToContext(cairo, pixmap_draw_rect, context, draw_rect.origin()); | |
| 408 cairo_destroy(cairo); | |
| 409 | |
| 410 // Construct the paint message, targeting the pixmap. | 403 // Construct the paint message, targeting the pixmap. |
| 411 NPEvent np_event = {0}; | 404 NPEvent np_event = {0}; |
| 412 XGraphicsExposeEvent &event = np_event.xgraphicsexpose; | 405 XGraphicsExposeEvent &event = np_event.xgraphicsexpose; |
| 413 event.type = GraphicsExpose; | 406 event.type = GraphicsExpose; |
| 414 event.display = GDK_DISPLAY(); | |
| 415 event.drawable = GDK_PIXMAP_XID(pixmap_); | |
| 416 event.x = pixmap_draw_rect.x(); | 407 event.x = pixmap_draw_rect.x(); |
| 417 event.y = pixmap_draw_rect.y(); | 408 event.y = pixmap_draw_rect.y(); |
| 418 event.width = pixmap_draw_rect.width(); | 409 event.width = pixmap_draw_rect.width(); |
| 419 event.height = pixmap_draw_rect.height(); | 410 event.height = pixmap_draw_rect.height(); |
| 411 event.display = GDK_DISPLAY(); |
| 420 | 412 |
| 421 // Tell the plugin to paint into the pixmap. | 413 if (windowless_shm_pixmap_ != None) { |
| 422 static StatsRate plugin_paint("Plugin.Paint"); | 414 Pixmap pixmap = None; |
| 423 StatsScope<StatsRate> scope(plugin_paint); | 415 GC xgc = NULL; |
| 424 NPError err = instance()->NPP_HandleEvent(&np_event); | 416 Display* display = event.display; |
| 425 DCHECK_EQ(err, NPERR_NO_ERROR); | 417 gfx::Rect plugin_draw_rect = draw_rect; |
| 426 | 418 |
| 427 cairo_save(context); | 419 // Make plugin_draw_rect relative to the plugin window. |
| 428 // Now copy the rendered image pixmap back into the drawing buffer. | 420 plugin_draw_rect.Offset(-window_rect_.x(), -window_rect_.y()); |
| 429 gdk_cairo_set_source_pixmap(context, pixmap_, -offset_x, -offset_y); | 421 |
| 430 cairo_rectangle(context, draw_rect.x(), draw_rect.y(), | 422 // In case the drawing area does not start with the plugin window origin, |
| 431 draw_rect.width(), draw_rect.height()); | 423 // we can not let the plugin directly draw over the shared memory pixmap. |
| 432 cairo_clip(context); | 424 if (plugin_draw_rect.x() != pixmap_draw_rect.x() || |
| 433 cairo_paint(context); | 425 plugin_draw_rect.y() != pixmap_draw_rect.y()) { |
| 426 pixmap = XCreatePixmap(display, windowless_shm_pixmap_, |
| 427 std::max(1, pixmap_rect.width()), |
| 428 std::max(1, pixmap_rect.height()), |
| 429 DefaultDepth(display, 0)); |
| 430 xgc = XCreateGC(display, windowless_shm_pixmap_, 0, NULL); |
| 431 // Copy the current image into the pixmap, so the plugin can draw over it. |
| 432 XCopyArea(display, windowless_shm_pixmap_, pixmap, xgc, |
| 433 plugin_draw_rect.x(), plugin_draw_rect.y(), |
| 434 pixmap_draw_rect.width(), pixmap_draw_rect.height(), |
| 435 pixmap_draw_rect.x(), pixmap_draw_rect.y()); |
| 436 |
| 437 event.drawable = pixmap; |
| 438 } else { |
| 439 event.drawable = windowless_shm_pixmap_; |
| 440 } |
| 441 |
| 442 // Tell the plugin to paint into the pixmap. |
| 443 static StatsRate plugin_paint("Plugin.Paint"); |
| 444 StatsScope<StatsRate> scope(plugin_paint); |
| 445 NPError err = instance()->NPP_HandleEvent(&np_event); |
| 446 DCHECK_EQ(err, NPERR_NO_ERROR); |
| 447 |
| 448 if (pixmap != None) { |
| 449 // Copy the rendered image pixmap back into the shm pixmap |
| 450 // and thus the drawing buffer. |
| 451 XCopyArea(display, pixmap, windowless_shm_pixmap_, xgc, |
| 452 pixmap_draw_rect.x(), pixmap_draw_rect.y(), |
| 453 pixmap_draw_rect.width(), pixmap_draw_rect.height(), |
| 454 plugin_draw_rect.x(), plugin_draw_rect.y()); |
| 455 XSync(display, FALSE); |
| 456 if (xgc) |
| 457 XFreeGC(display, xgc); |
| 458 XFreePixmap(display, pixmap); |
| 459 } else { |
| 460 XSync(display, FALSE); |
| 461 } |
| 462 } else { |
| 463 EnsurePixmapAtLeastSize(pixmap_rect.width(), pixmap_rect.height()); |
| 464 |
| 465 // Copy the current image into the pixmap, so the plugin can draw over |
| 466 // this background. |
| 467 cairo_t* cairo = gdk_cairo_create(pixmap_); |
| 468 BlitContextToContext(cairo, pixmap_draw_rect, context, draw_rect.origin()); |
| 469 cairo_destroy(cairo); |
| 470 |
| 471 event.drawable = GDK_PIXMAP_XID(pixmap_); |
| 472 |
| 473 // Tell the plugin to paint into the pixmap. |
| 474 static StatsRate plugin_paint("Plugin.Paint"); |
| 475 StatsScope<StatsRate> scope(plugin_paint); |
| 476 NPError err = instance()->NPP_HandleEvent(&np_event); |
| 477 DCHECK_EQ(err, NPERR_NO_ERROR); |
| 478 |
| 479 cairo_save(context); |
| 480 // Now copy the rendered image pixmap back into the drawing buffer. |
| 481 gdk_cairo_set_source_pixmap(context, pixmap_, -offset_x, -offset_y); |
| 482 cairo_rectangle(context, draw_rect.x(), draw_rect.y(), |
| 483 draw_rect.width(), draw_rect.height()); |
| 484 cairo_clip(context); |
| 485 cairo_paint(context); |
| 434 | 486 |
| 435 #ifdef DEBUG_RECTANGLES | 487 #ifdef DEBUG_RECTANGLES |
| 436 // Draw some debugging rectangles. | 488 // Draw some debugging rectangles. |
| 437 // Pixmap rect = blue. | 489 // Pixmap rect = blue. |
| 438 DrawDebugRectangle(context, pixmap_rect, 0, 0, 1); | 490 DrawDebugRectangle(context, pixmap_rect, 0, 0, 1); |
| 439 // Drawing rect = red. | 491 // Drawing rect = red. |
| 440 DrawDebugRectangle(context, draw_rect, 1, 0, 0); | 492 DrawDebugRectangle(context, draw_rect, 1, 0, 0); |
| 441 #endif | 493 #endif |
| 442 cairo_restore(context); | 494 cairo_restore(context); |
| 495 } |
| 443 } | 496 } |
| 444 | 497 |
| 445 void WebPluginDelegateImpl::WindowlessSetWindow() { | 498 void WebPluginDelegateImpl::WindowlessSetWindow() { |
| 446 if (!instance()) | 499 if (!instance()) |
| 447 return; | 500 return; |
| 448 | 501 |
| 449 if (window_rect_.IsEmpty()) // wait for geometry to be set. | 502 if (window_rect_.IsEmpty()) // wait for geometry to be set. |
| 450 return; | 503 return; |
| 451 | 504 |
| 452 DCHECK(instance()->windowless()); | 505 DCHECK(instance()->windowless()); |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 if (event->event == WM_MOUSEMOVE) { | 753 if (event->event == WM_MOUSEMOVE) { |
| 701 // Snag a reference to the current cursor ASAP in case the plugin modified | 754 // Snag a reference to the current cursor ASAP in case the plugin modified |
| 702 // it. There is a nasty race condition here with the multiprocess browser | 755 // it. There is a nasty race condition here with the multiprocess browser |
| 703 // as someone might be setting the cursor in the main process as well. | 756 // as someone might be setting the cursor in the main process as well. |
| 704 *cursor = current_windowless_cursor_; | 757 *cursor = current_windowless_cursor_; |
| 705 } | 758 } |
| 706 #endif | 759 #endif |
| 707 | 760 |
| 708 return ret; | 761 return ret; |
| 709 } | 762 } |
| OLD | NEW |