| Index: webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
|
| ===================================================================
|
| --- webkit/glue/plugins/webplugin_delegate_impl_gtk.cc (revision 54851)
|
| +++ webkit/glue/plugins/webplugin_delegate_impl_gtk.cc (working copy)
|
| @@ -44,6 +44,7 @@
|
| windowless_(false),
|
| plugin_(NULL),
|
| instance_(instance),
|
| + windowless_shm_pixmap_(None),
|
| pixmap_(NULL),
|
| first_event_time_(-1.0),
|
| plug_(NULL),
|
| @@ -399,47 +400,99 @@
|
| pixmap_draw_rect.right(),
|
| pixmap_draw_rect.bottom());
|
|
|
| - EnsurePixmapAtLeastSize(pixmap_rect.width(), pixmap_rect.height());
|
| -
|
| - // Copy the current image into the pixmap, so the plugin can draw over
|
| - // this background.
|
| - cairo_t* cairo = gdk_cairo_create(pixmap_);
|
| - BlitContextToContext(cairo, pixmap_draw_rect, context, draw_rect.origin());
|
| - cairo_destroy(cairo);
|
| -
|
| // Construct the paint message, targeting the pixmap.
|
| NPEvent np_event = {0};
|
| XGraphicsExposeEvent &event = np_event.xgraphicsexpose;
|
| event.type = GraphicsExpose;
|
| - event.display = GDK_DISPLAY();
|
| - event.drawable = GDK_PIXMAP_XID(pixmap_);
|
| event.x = pixmap_draw_rect.x();
|
| event.y = pixmap_draw_rect.y();
|
| event.width = pixmap_draw_rect.width();
|
| event.height = pixmap_draw_rect.height();
|
| + event.display = GDK_DISPLAY();
|
|
|
| - // Tell the plugin to paint into the pixmap.
|
| - static StatsRate plugin_paint("Plugin.Paint");
|
| - StatsScope<StatsRate> scope(plugin_paint);
|
| - NPError err = instance()->NPP_HandleEvent(&np_event);
|
| - DCHECK_EQ(err, NPERR_NO_ERROR);
|
| + if (windowless_shm_pixmap_ != None) {
|
| + Pixmap pixmap = None;
|
| + GC xgc = NULL;
|
| + Display* display = event.display;
|
| + gfx::Rect plugin_draw_rect = draw_rect;
|
|
|
| - cairo_save(context);
|
| - // Now copy the rendered image pixmap back into the drawing buffer.
|
| - gdk_cairo_set_source_pixmap(context, pixmap_, -offset_x, -offset_y);
|
| - cairo_rectangle(context, draw_rect.x(), draw_rect.y(),
|
| - draw_rect.width(), draw_rect.height());
|
| - cairo_clip(context);
|
| - cairo_paint(context);
|
| + // Make plugin_draw_rect relative to the plugin window.
|
| + plugin_draw_rect.Offset(-window_rect_.x(), -window_rect_.y());
|
|
|
| + // In case the drawing area does not start with the plugin window origin,
|
| + // we can not let the plugin directly draw over the shared memory pixmap.
|
| + if (plugin_draw_rect.x() != pixmap_draw_rect.x() ||
|
| + plugin_draw_rect.y() != pixmap_draw_rect.y()) {
|
| + pixmap = XCreatePixmap(display, windowless_shm_pixmap_,
|
| + std::max(1, pixmap_rect.width()),
|
| + std::max(1, pixmap_rect.height()),
|
| + DefaultDepth(display, 0));
|
| + xgc = XCreateGC(display, windowless_shm_pixmap_, 0, NULL);
|
| + // Copy the current image into the pixmap, so the plugin can draw over it.
|
| + XCopyArea(display, windowless_shm_pixmap_, pixmap, xgc,
|
| + plugin_draw_rect.x(), plugin_draw_rect.y(),
|
| + pixmap_draw_rect.width(), pixmap_draw_rect.height(),
|
| + pixmap_draw_rect.x(), pixmap_draw_rect.y());
|
| +
|
| + event.drawable = pixmap;
|
| + } else {
|
| + event.drawable = windowless_shm_pixmap_;
|
| + }
|
| +
|
| + // Tell the plugin to paint into the pixmap.
|
| + static StatsRate plugin_paint("Plugin.Paint");
|
| + StatsScope<StatsRate> scope(plugin_paint);
|
| + NPError err = instance()->NPP_HandleEvent(&np_event);
|
| + DCHECK_EQ(err, NPERR_NO_ERROR);
|
| +
|
| + if (pixmap != None) {
|
| + // Copy the rendered image pixmap back into the shm pixmap
|
| + // and thus the drawing buffer.
|
| + XCopyArea(display, pixmap, windowless_shm_pixmap_, xgc,
|
| + pixmap_draw_rect.x(), pixmap_draw_rect.y(),
|
| + pixmap_draw_rect.width(), pixmap_draw_rect.height(),
|
| + plugin_draw_rect.x(), plugin_draw_rect.y());
|
| + XSync(display, FALSE);
|
| + if (xgc)
|
| + XFreeGC(display, xgc);
|
| + XFreePixmap(display, pixmap);
|
| + } else {
|
| + XSync(display, FALSE);
|
| + }
|
| + } else {
|
| + EnsurePixmapAtLeastSize(pixmap_rect.width(), pixmap_rect.height());
|
| +
|
| + // Copy the current image into the pixmap, so the plugin can draw over
|
| + // this background.
|
| + cairo_t* cairo = gdk_cairo_create(pixmap_);
|
| + BlitContextToContext(cairo, pixmap_draw_rect, context, draw_rect.origin());
|
| + cairo_destroy(cairo);
|
| +
|
| + event.drawable = GDK_PIXMAP_XID(pixmap_);
|
| +
|
| + // Tell the plugin to paint into the pixmap.
|
| + static StatsRate plugin_paint("Plugin.Paint");
|
| + StatsScope<StatsRate> scope(plugin_paint);
|
| + NPError err = instance()->NPP_HandleEvent(&np_event);
|
| + DCHECK_EQ(err, NPERR_NO_ERROR);
|
| +
|
| + cairo_save(context);
|
| + // Now copy the rendered image pixmap back into the drawing buffer.
|
| + gdk_cairo_set_source_pixmap(context, pixmap_, -offset_x, -offset_y);
|
| + cairo_rectangle(context, draw_rect.x(), draw_rect.y(),
|
| + draw_rect.width(), draw_rect.height());
|
| + cairo_clip(context);
|
| + cairo_paint(context);
|
| +
|
| #ifdef DEBUG_RECTANGLES
|
| - // Draw some debugging rectangles.
|
| - // Pixmap rect = blue.
|
| - DrawDebugRectangle(context, pixmap_rect, 0, 0, 1);
|
| - // Drawing rect = red.
|
| - DrawDebugRectangle(context, draw_rect, 1, 0, 0);
|
| + // Draw some debugging rectangles.
|
| + // Pixmap rect = blue.
|
| + DrawDebugRectangle(context, pixmap_rect, 0, 0, 1);
|
| + // Drawing rect = red.
|
| + DrawDebugRectangle(context, draw_rect, 1, 0, 0);
|
| #endif
|
| - cairo_restore(context);
|
| + cairo_restore(context);
|
| + }
|
| }
|
|
|
| void WebPluginDelegateImpl::WindowlessSetWindow() {
|
|
|