Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Unified Diff: webkit/glue/plugins/webplugin_delegate_impl_gtk.cc

Issue 56160: Linux: more windowless plugin work. (Closed)
Patch Set: typo Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
index 8d20186f23feb958b3602b50b41f669d36905228..4922bf48a054e8f0c229d786ba4c09bce1384baa 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
@@ -171,9 +171,8 @@ void WebPluginDelegateImpl::UpdateGeometry(
void WebPluginDelegateImpl::Paint(cairo_surface_t* context,
const gfx::Rect& rect) {
- if (windowless_) {
+ if (windowless_)
WindowlessPaint(context, rect);
- }
}
void WebPluginDelegateImpl::Print(cairo_surface_t* context) {
@@ -460,6 +459,25 @@ void WebPluginDelegateImpl::EnsurePixmapAtLeastSize(int width, int height) {
gdk_drawable_set_colormap(GDK_DRAWABLE(pixmap_), colormap);
}
+#ifdef DEBUG_RECTANGLES
+namespace {
+
+// Draw a rectangle on a Cairo surface.
+// Useful for debugging various rectangles involved in drawing plugins.
+void DrawDebugRectangle(cairo_surface_t* surface,
+ const gfx::Rect& rect,
+ float r, float g, float b) {
+ cairo_t* cairo = cairo_create(surface);
+ cairo_set_source_rgba(cairo, r, g, b, 0.5);
+ cairo_rectangle(cairo, rect.x(), rect.y(),
+ rect.width(), rect.height());
+ cairo_stroke(cairo);
+ cairo_destroy(cairo);
+}
+
+} // namespace
+#endif
+
void WebPluginDelegateImpl::WindowlessPaint(cairo_surface_t* context,
const gfx::Rect& damage_rect) {
// Compare to:
@@ -482,12 +500,47 @@ void WebPluginDelegateImpl::WindowlessPaint(cairo_surface_t* context,
if (windowless_needs_set_window_)
WindowlessSetWindow(false);
- EnsurePixmapAtLeastSize(damage_rect.width(), damage_rect.height());
+ // The actual dirty region is just the intersection of the plugin
+ // window with the damage region. However, the plugin wants to draw
+ // relative to the containing window's origin, so our pixmap must be
+ // from the window's origin down to the bottom-right edge of the
+ // dirty region.
+ //
+ // +-----------------------------+-----------------------------+
+ // | | |
+ // | pixmap +-------------+ |
+ // | | damage | window |
+ // | | | |
+ // | +-------+-------------+----------+ |
+ // | | | draw | | |
+ // +-------+-------+-------------+ | |
+ // | | | |
+ // | | plugin | |
+ // | +--------------------------------+ |
+ // | |
+ // | |
+ // +-----------------------------------------------------------+
+ //
+ // TOOD(evanm): on Windows, we instead just translate the origin of
+ // the DC that we hand to the plugin. Does such a thing exist on X?
+ // TODO(evanm): make use of the clip rect as well.
+
+ gfx::Rect plugin_rect(window_.x, window_.y, window_.width, window_.height);
+ gfx::Rect draw_rect = plugin_rect.Intersect(damage_rect);
+
+ gfx::Rect pixmap_rect(0, 0,
+ draw_rect.x() + draw_rect.width(),
+ draw_rect.y() + draw_rect.height());
+
+ 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_);
cairo_set_source_surface(cairo, context, 0, 0);
+ cairo_rectangle(cairo, draw_rect.x(), draw_rect.y(),
+ draw_rect.width(), draw_rect.height());
+ cairo_clip(cairo);
cairo_paint(cairo);
cairo_destroy(cairo);
@@ -496,10 +549,10 @@ void WebPluginDelegateImpl::WindowlessPaint(cairo_surface_t* context,
event.type = GraphicsExpose;
event.display = GDK_DISPLAY();
event.drawable = GDK_PIXMAP_XID(pixmap_);
- event.x = damage_rect.x();
- event.y = damage_rect.y();
- event.width = damage_rect.width();
- event.height = damage_rect.height();
+ event.x = draw_rect.x();
+ event.y = draw_rect.y();
+ event.width = draw_rect.width();
+ event.height = draw_rect.height();
// Tell the plugin to paint into the pixmap.
static StatsRate plugin_paint("Plugin.Paint");
@@ -510,8 +563,19 @@ void WebPluginDelegateImpl::WindowlessPaint(cairo_surface_t* context,
// Now copy the rendered image pixmap back into the drawing buffer.
cairo = cairo_create(context);
gdk_cairo_set_source_pixmap(cairo, pixmap_, 0, 0);
+ cairo_rectangle(cairo, draw_rect.x(), draw_rect.y(),
+ draw_rect.width(), draw_rect.height());
+ cairo_clip(cairo);
cairo_paint(cairo);
cairo_destroy(cairo);
+
+#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);
+#endif
}
void WebPluginDelegateImpl::WindowlessSetWindow(bool force_set_window) {
@@ -568,87 +632,18 @@ void WebPluginDelegateImpl::SetFocus() {
bool WebPluginDelegateImpl::HandleEvent(NPEvent* event,
WebCursor* cursor) {
- NOTIMPLEMENTED();
-#if 0
- DCHECK(windowless_) << "events should only be received in windowless mode";
- DCHECK(cursor != NULL);
-
- // To ensure that the plugin receives keyboard events we set focus to the
- // dummy window.
- // TODO(iyengar) We need a framework in the renderer to identify which
- // windowless plugin is under the mouse and to handle this. This would
- // also require some changes in RenderWidgetHost to detect this in the
- // WM_MOUSEACTIVATE handler and inform the renderer accordingly.
- HWND prev_focus_window = NULL;
- if (event->event == WM_RBUTTONDOWN) {
- prev_focus_window = ::SetFocus(dummy_window_for_activation_);
- }
-
- if (ShouldTrackEventForModalLoops(event)) {
- // A windowless plugin can enter a modal loop in a NPP_HandleEvent call.
- // For e.g. Flash puts up a context menu when we right click on the
- // windowless plugin area. We detect this by setting up a message filter
- // hook pror to calling NPP_HandleEvent on the plugin and unhook on
- // return from NPP_HandleEvent. If the plugin does enter a modal loop
- // in that context we unhook on receiving the first notification in
- // the message filter hook.
- handle_event_message_filter_hook_ =
- SetWindowsHookEx(WH_MSGFILTER, HandleEventMessageFilterHook, NULL,
- GetCurrentThreadId());
- }
-
- bool old_task_reentrancy_state =
- MessageLoop::current()->NestableTasksAllowed();
-
- current_plugin_instance_ = this;
-
- handle_event_depth_++;
-
- bool pop_user_gesture = false;
-
- if (IsUserGestureMessage(event->event)) {
- pop_user_gesture = true;
- instance()->PushPopupsEnabledState(true);
- }
-
bool ret = instance()->NPP_HandleEvent(event) != 0;
+#if 0
if (event->event == WM_MOUSEMOVE) {
// Snag a reference to the current cursor ASAP in case the plugin modified
// it. There is a nasty race condition here with the multiprocess browser
// as someone might be setting the cursor in the main process as well.
*cursor = current_windowless_cursor_;
}
-
- if (pop_user_gesture) {
- instance()->PopPopupsEnabledState();
- }
-
- handle_event_depth_--;
-
- current_plugin_instance_ = NULL;
-
- MessageLoop::current()->SetNestableTasksAllowed(old_task_reentrancy_state);
-
- if (handle_event_message_filter_hook_) {
- UnhookWindowsHookEx(handle_event_message_filter_hook_);
- handle_event_message_filter_hook_ = NULL;
- }
-
- // We could have multiple NPP_HandleEvent calls nested together in case
- // the plugin enters a modal loop. Reset the pump messages event when
- // the outermost NPP_HandleEvent call unwinds.
- if (handle_event_depth_ == 0) {
- ResetEvent(handle_event_pump_messages_event_);
- }
-
- if (event->event == WM_RBUTTONUP && ::IsWindow(prev_focus_window)) {
- ::SetFocus(prev_focus_window);
- }
+#endif
return ret;
-#endif
- return 0;
}
WebPluginResourceClient* WebPluginDelegateImpl::CreateResourceClient(
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698