[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

girish at forwardbias.in girish at forwardbias.in
Wed Apr 7 23:51:29 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit d3d328e9a6a02e8d0354ede236f2d7fb3c5f8f82
Author: girish at forwardbias.in <girish at forwardbias.in@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Nov 20 11:18:31 2009 +0000

    [Qt] Implement support for rendering plugins on Qt/Mac when a page is used
    without a QWebView or when inside QGraphicsWebView.
    
    Reviewed by Simon Hausmann.
    
    Patch by Yongjun Zhang <yongjun.zhang at nokia.com> and
             Girish Ramakrishnan <girish at forwardbias.in>
    
    Currently, the code provides the cgcontext of the PlatformPluginWidget to
    the plugin. This approach does not work when we are printing, or using
    QWebFrame::render() to render to a QImage/QPixmap since the plugin ends
    up drawing on the QWebView (i.e platformPluginWidget's cgcontext) instead
    of the QPaintDevice's context.
    
    To solve all cases and keep the code simple, we render the plugin to an
    offscreen pixmap in all cases. This way, the plugin always renders to the
    CGContext of the pixmap and we then use QPainter to blit the pixmap into
    the QPaintDevice. We also create a fake window and set it's WindowRef in
    NPWindow. Only with this WindowRef does Flash paint correctly to the QPixmap.
    
    Now, that's the theory. In practice, ATM, mouse events do not work when using
    the fake window. So, setPlatformPluginWidget() is still called when using QWebView
    so that there are no regressions after this patch. Once we get mouse events
    working, setPlatformPluginWidget will be removed.
    
    https://bugs.webkit.org/show_bug.cgi?id=31183
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@51234 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index bfb93cb..49504b2 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,43 @@
+2009-11-18  Girish Ramakrishnan  <girish at forwardbias.in>
+
+        Reviewed by Simon Hausmann.
+
+        Patch by Yongjun Zhang <yongjun.zhang at nokia.com> and
+                 Girish Ramakrishnan <girish at forwardbias.in>
+        
+        [Qt] Implement support for rendering plugins on Qt/Mac when a page is used
+        without a QWebView or when inside QGraphicsWebView.
+        
+        Currently, the code provides the cgcontext of the PlatformPluginWidget to
+        the plugin. This approach does not work when we are printing, or using
+        QWebFrame::render() to render to a QImage/QPixmap since the plugin ends
+        up drawing on the QWebView (i.e platformPluginWidget's cgcontext) instead
+        of the QPaintDevice's context.
+        
+        To solve all cases and keep the code simple, we render the plugin to an
+        offscreen pixmap in all cases. This way, the plugin always renders to the
+        CGContext of the pixmap and we then use QPainter to blit the pixmap into
+        the QPaintDevice. We also create a fake window and set it's WindowRef in
+        NPWindow. Only with this WindowRef does Flash paint correctly to the QPixmap.
+        
+        Now, that's the theory. In practice, ATM, mouse events do not work when using
+        the fake window. So, setPlatformPluginWidget() is still called when using QWebView
+        so that there are no regressions after this patch. Once we get mouse events
+        working, setPlatformPluginWidget will be removed.
+        
+        https://bugs.webkit.org/show_bug.cgi?id=31183
+
+        * plugins/PluginView.cpp:
+        (WebCore::PluginView::PluginView):
+        * plugins/PluginView.h:
+        * plugins/mac/PluginViewMac.cpp:
+        (WebCore::PluginView::platformStart):
+        (WebCore::PluginView::platformDestroy):
+        (WebCore::PluginView::setNPWindowIfNeeded):
+        (WebCore::PluginView::updatePluginWidget):
+        (WebCore::PluginView::paint):
+        (WebCore::PluginView::invalidateRect):
+
 2009-11-19  Joseph Pecoraro  <joepeck at webkit.org>
 
         Reviewed by Timothy Hatcher.
diff --git a/WebCore/plugins/PluginView.cpp b/WebCore/plugins/PluginView.cpp
index 25092d9..ac210f6 100644
--- a/WebCore/plugins/PluginView.cpp
+++ b/WebCore/plugins/PluginView.cpp
@@ -815,6 +815,8 @@ PluginView::PluginView(Frame* parentFrame, const IntSize& size, PluginPackage* p
 #if defined(XP_MACOSX)
     , m_drawingModel(NPDrawingModel(-1))
     , m_eventModel(NPEventModel(-1))
+    , m_contextRef(0)
+    , m_fakeWindow(0)
 #endif
 #if defined(Q_WS_X11) && ENABLE(NETSCAPE_PLUGIN_API)
     , m_hasPendingGeometryChange(true)
diff --git a/WebCore/plugins/PluginView.h b/WebCore/plugins/PluginView.h
index fd86187..57b1f9b 100644
--- a/WebCore/plugins/PluginView.h
+++ b/WebCore/plugins/PluginView.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Collabora Ltd. All rights reserved.
+ * Copyright (C) 2009 Girish Ramakrishnan <girish at forwardbias.in>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -50,6 +51,9 @@ typedef struct HWND__* HWND;
 typedef HWND PlatformPluginWidget;
 #else
 typedef PlatformWidget PlatformPluginWidget;
+#if defined(XP_MACOSX) && PLATFORM(QT)
+#include <QPixmap>
+#endif
 #endif
 
 namespace JSC {
@@ -326,6 +330,11 @@ private:
         NP_CGContext m_npCgContext;
         NPDrawingModel m_drawingModel;
         NPEventModel m_eventModel;
+        CGContextRef m_contextRef;
+        WindowRef m_fakeWindow;
+#if PLATFORM(QT)
+        QPixmap m_pixmap;
+#endif
 
         void setNPWindowIfNeeded();
         Point globalMousePosForPlugin() const;
diff --git a/WebCore/plugins/mac/PluginViewMac.cpp b/WebCore/plugins/mac/PluginViewMac.cpp
index d4bffcd..6044313 100644
--- a/WebCore/plugins/mac/PluginViewMac.cpp
+++ b/WebCore/plugins/mac/PluginViewMac.cpp
@@ -2,6 +2,7 @@
  * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
  * Copyright (C) 2008 Collabora Ltd. All rights reserved.
  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2009 Girish Ramakrishnan <girish at forwardbias.in>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -75,6 +76,7 @@ using JSC::UString;
 #if PLATFORM(QT)
 #include <QWidget>
 #include <QKeyEvent>
+#include <QPainter>
 #include "QWebPageClient.h"
 QT_BEGIN_NAMESPACE
 #if QT_VERSION < 0x040500
@@ -173,13 +175,20 @@ bool PluginView::platformStart()
     }
 
 #if PLATFORM(QT)
+    // Set the platformPluginWidget only in the case of QWebView until we get mouse events working. 
+    // In all other cases, we use off-screen rendering
     if (QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient()) {
-        if (QWidget* widget = client->ownerWidget()) {
+        if (QWidget* widget = qobject_cast<QWidget*>(client->pluginParent()))
             setPlatformPluginWidget(widget);
-        }
     }
 #endif
 
+    // Create a fake window relative to which all events will be sent when using offscreen rendering
+    if (!platformPluginWidget()) {
+        ::Rect windowBounds = { 0, 0, 100, 100 };
+        CreateNewWindow(kDocumentWindowClass, kWindowStandardDocumentAttributes, &windowBounds, &m_fakeWindow);
+    }
+
     show();
 
     return true;
@@ -189,6 +198,11 @@ void PluginView::platformDestroy()
 {
     if (platformPluginWidget())
         setPlatformPluginWidget(0);
+    else {
+        CGContextRelease(m_contextRef);
+        if (m_fakeWindow)
+            DisposeWindow(m_fakeWindow);
+    }
 }
 
 // Used before the plugin view has been initialized properly, and as a
@@ -353,15 +367,21 @@ void PluginView::setNPWindowIfNeeded()
     if (!m_isStarted || !parent() || !m_plugin->pluginFuncs()->setwindow)
         return;
 
-    CGContextRef newContextRef = cgHandleFor(platformPluginWidget());
-    if (!newContextRef)
-        return;
+    CGContextRef newContextRef = 0;
+    WindowRef newWindowRef = 0;
+    if (platformPluginWidget()) {
+        newContextRef = cgHandleFor(platformPluginWidget());
+        newWindowRef = nativeWindowFor(platformPluginWidget());
+        m_npWindow.type = NPWindowTypeWindow;
+    } else {
+        newContextRef = m_contextRef;
+        newWindowRef = m_fakeWindow;
+        m_npWindow.type = NPWindowTypeDrawable;
+    }
 
-    WindowRef newWindowRef = nativeWindowFor(platformPluginWidget());
-    if (!newWindowRef)
+    if (!newContextRef || !newWindowRef)
         return;
 
-    m_npWindow.type = NPWindowTypeWindow;
     m_npWindow.window = (void*)&m_npCgContext;
     m_npCgContext.window = newWindowRef;
     m_npCgContext.context = newContextRef;
@@ -405,6 +425,17 @@ void PluginView::updatePluginWidget()
     IntPoint offset = topLevelOffsetFor(platformPluginWidget());
     m_windowRect.move(offset.x(), offset.y());
 
+    if (!platformPluginWidget()) {
+        if (m_windowRect.size() != oldWindowRect.size()) {
+            CGContextRelease(m_contextRef);
+#if PLATFORM(QT)
+            m_pixmap = QPixmap(m_windowRect.size());
+            m_pixmap.fill(Qt::transparent);
+            m_contextRef = qt_mac_cg_context(&m_pixmap);
+#endif
+        }
+    }
+
     m_clipRect = windowClipRect();
     m_clipRect.move(-m_windowRect.x(), -m_windowRect.y());
 
@@ -429,8 +460,29 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect)
         return;
 
     CGContextSaveGState(cgContext);
-    IntPoint offset = frameRect().location();
-    CGContextTranslateCTM(cgContext, offset.x(), offset.y());
+    if (platformPluginWidget()) {
+        IntPoint offset = frameRect().location();
+        CGContextTranslateCTM(cgContext, offset.x(), offset.y());
+    }
+
+    IntRect targetRect(frameRect());
+    targetRect.intersects(rect);
+
+    // clip the context so that plugin only updates the interested area.
+    CGRect r;
+    r.origin.x = targetRect.x() - frameRect().x();
+    r.origin.y = targetRect.y() - frameRect().y();
+    r.size.width = targetRect.width();
+    r.size.height = targetRect.height();
+    CGContextClipToRect(cgContext, r);
+
+    if (!platformPluginWidget() && m_isTransparent) { // clean the pixmap in transparent mode
+#if PLATFORM(QT)
+        QPainter painter(&m_pixmap);
+        painter.setCompositionMode(QPainter::CompositionMode_Clear);
+        painter.fillRect(QRectF(r.origin.x, r.origin.y, r.size.width, r.size.height), Qt::transparent);
+#endif
+    }
 
     EventRecord event;
     event.what = updateEvt;
@@ -444,18 +496,28 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect)
         LOG(Events, "PluginView::paint(): Paint event not accepted");
 
     CGContextRestoreGState(cgContext);
+
+    if (!platformPluginWidget()) {
+#if PLATFORM(QT)
+        QPainter* painter = context->platformContext();
+        painter->drawPixmap(targetRect.x(), targetRect.y(), m_pixmap, 
+                            targetRect.x() - frameRect().x(), targetRect.y() - frameRect().y(), targetRect.width(), targetRect.height());
+#endif
+    }
 }
 
 void PluginView::invalidateRect(const IntRect& rect)
 {
     if (platformPluginWidget())
         platformPluginWidget()->update(convertToContainingWindow(rect));
+    else
+        invalidateWindowlessPluginRect(rect);
 }
 
 void PluginView::invalidateRect(NPRect* rect)
 {
-    // TODO: optimize
-    invalidate();
+    IntRect r(rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top);
+    invalidateRect(r);
 }
 
 void PluginView::invalidateRegion(NPRegion region)

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list