Pass the right dirty rect to Plugin::paint

A typo in r79040 broke this. Much of this patch is just support for testing the fix.

Fixes <http://webkit.org/b/55365> <rdar://problem/9031089> REGRESSION (r79040): WebKit2:
Large portions of pages with plugins paint black

Reviewed by Anders Carlsson.

Source/WebKit2:

* WebProcess/Plugins/PluginView.cpp:
(WebKit::PluginView::paint): Pass the dirty rect we calculated earlier to Plugin::paint,
rather than just passing along the dirty rect that was passed into this function. This is
the bug fix.

* WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
(WKBundlePageForceRepaint):
* WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h:
Added new SPI. Just calls through to WebPage::forceRepaintWithoutCallback.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::forceRepaintWithoutCallback): Moved code to force a repaint here...
(WebKit::WebPage::forceRepaint): ...from here.

* WebProcess/WebPage/WebPage.h: Added forceRepaintWithoutCallback.

Tools:

Add a test for the paint rect passed via WM_PAINT to windowless plugins

* DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp:
(PluginTest::NPP_HandleEvent):
* DumpRenderTree/TestNetscapePlugIn/PluginTest.h:
Added NPP_HandleEvent. Just returns 0 at this level.

* DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowlessPaintRectCoordinates.cpp: Added.
(WindowlessPaintRectCoordinates::WindowlessPaintRectCoordinates): Call up to the base class.
(WindowlessPaintRectCoordinates::NPP_New): Mark ourselves as windowless.
(WindowlessPaintRectCoordinates::NPP_HandleEvent): Check that the paint rect passed via
WM_PAINT has the expected coordinates.

* DumpRenderTree/TestNetscapePlugIn/main.cpp:
(NPP_HandleEvent): Give the PluginTest a chance to handle the event before doing anything
else.

* DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj: Added new file, let VS
resort things.

* WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
(WTR::InjectedBundlePage::didFinishLoadForFrame): Added a call to WKBundlePageForceRepaint.
This is roughly equivalent to the call to -[WebView displayIfNeeded] in -[FrameLoadDelegate
webView:didFinishLoadForFrame:] in DumpRenderTree.

* WebKitTestRunner/win/PlatformWebViewWin.cpp:
(WTR::PlatformWebView::PlatformWebView): Tell the WKView it's in a window so that plugins
can start running.

LayoutTests:

Add a test for the paint rect passed via WM_PAINT to windowless plugins

* platform/win-wk2/platform/win/plugins/windowless-paint-rect-coordinates-expected.txt: Added.
* platform/win/plugins/windowless-paint-rect-coordinates-expected.txt: Added. WebKit1
doesn't pass a paint rect via WM_PAINT, so we have different results there.
* platform/win/plugins/windowless-paint-rect-coordinates.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@79863 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 1401acf..f182026 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,17 @@
+2011-02-28  Adam Roben  <aroben@apple.com>
+
+        Add a test for the paint rect passed via WM_PAINT to windowless plugins
+
+        Test for <http://webkit.org/b/55365> <rdar://problem/9031089> REGRESSION (r79040): WebKit2:
+        Large portions of pages with plugins paint black
+
+        Reviewed by Anders Carlsson.
+
+        * platform/win-wk2/platform/win/plugins/windowless-paint-rect-coordinates-expected.txt: Added.
+        * platform/win/plugins/windowless-paint-rect-coordinates-expected.txt: Added. WebKit1
+        doesn't pass a paint rect via WM_PAINT, so we have different results there.
+        * platform/win/plugins/windowless-paint-rect-coordinates.html: Added.
+
 2011-02-28  Vsevolod Vlasov  <vsevik@chromium.org>
 
         Reviewed by Pavel Feldman.
diff --git a/LayoutTests/platform/win-wk2/platform/win/plugins/windowless-paint-rect-coordinates-expected.txt b/LayoutTests/platform/win-wk2/platform/win/plugins/windowless-paint-rect-coordinates-expected.txt
new file mode 100644
index 0000000..f4bee7f
--- /dev/null
+++ b/LayoutTests/platform/win-wk2/platform/win/plugins/windowless-paint-rect-coordinates-expected.txt
@@ -0,0 +1,3 @@
+CONSOLE MESSAGE: line 0: PLUGIN: Success
+
+This tests that the paint rect passed in WM_PAINT has the expected coordinates.
diff --git a/LayoutTests/platform/win/plugins/windowless-paint-rect-coordinates-expected.txt b/LayoutTests/platform/win/plugins/windowless-paint-rect-coordinates-expected.txt
new file mode 100644
index 0000000..53d4993
--- /dev/null
+++ b/LayoutTests/platform/win/plugins/windowless-paint-rect-coordinates-expected.txt
@@ -0,0 +1,3 @@
+CONSOLE MESSAGE: line 0: PLUGIN: A null paint rect was passed in the WM_PAINT event
+
+This tests that the paint rect passed in WM_PAINT has the expected coordinates.
diff --git a/LayoutTests/platform/win/plugins/windowless-paint-rect-coordinates.html b/LayoutTests/platform/win/plugins/windowless-paint-rect-coordinates.html
new file mode 100644
index 0000000..ce86f48
--- /dev/null
+++ b/LayoutTests/platform/win/plugins/windowless-paint-rect-coordinates.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script>
+        if (window.layoutTestController)
+            layoutTestController.dumpAsText();
+    </script>
+    <style>
+        embed {
+            position: absolute;
+            /* Keep these values in sync with WindowlessPaintRectCoordinates::NPP_HandleEvent. */
+            top: 100px;
+            left: 100px;
+            width: 100px;
+            height: 100px;
+        }
+    </style>
+</head>
+<body>
+    <embed type="application/x-webkit-test-netscape" test="windowless-paint-rect-coordinates"></embed>
+    <p>This tests that the paint rect passed in WM_PAINT has the expected coordinates.</p>
+</body>
+</html>
+
diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog
index a5145c2..5a4c9a4 100644
--- a/Source/WebKit2/ChangeLog
+++ b/Source/WebKit2/ChangeLog
@@ -1,3 +1,30 @@
+2011-02-28  Adam Roben  <aroben@apple.com>
+
+        Pass the right dirty rect to Plugin::paint
+
+        A typo in r79040 broke this. Much of this patch is just support for testing the fix.
+
+        Fixes <http://webkit.org/b/55365> <rdar://problem/9031089> REGRESSION (r79040): WebKit2:
+        Large portions of pages with plugins paint black
+
+        Reviewed by Anders Carlsson.
+
+        * WebProcess/Plugins/PluginView.cpp:
+        (WebKit::PluginView::paint): Pass the dirty rect we calculated earlier to Plugin::paint,
+        rather than just passing along the dirty rect that was passed into this function. This is
+        the bug fix.
+
+        * WebProcess/InjectedBundle/API/c/WKBundlePage.cpp:
+        (WKBundlePageForceRepaint):
+        * WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h:
+        Added new SPI. Just calls through to WebPage::forceRepaintWithoutCallback.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::forceRepaintWithoutCallback): Moved code to force a repaint here...
+        (WebKit::WebPage::forceRepaint): ...from here.
+
+        * WebProcess/WebPage/WebPage.h: Added forceRepaintWithoutCallback.
+
 2011-02-27  Sam Weinig  <sam@webkit.org>
 
         Reviewed by Dan Bernstein.
diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp
index a1a4da3..58052c5 100644
--- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp
+++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp
@@ -212,3 +212,8 @@
     return toAPI(toImpl(pageRef)->inspector());
 }
 #endif
+
+void WKBundlePageForceRepaint(WKBundlePageRef page)
+{
+    toImpl(page)->forceRepaintWithoutCallback();
+}
diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h
index 4bc8fed..b9dce68 100644
--- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h
+++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h
@@ -45,6 +45,8 @@
 WK_EXPORT double WKBundlePageGetPageZoomFactor(WKBundlePageRef page);
 WK_EXPORT void WKBundlePageSetPageZoomFactor(WKBundlePageRef page, double zoomFactor);
 
+WK_EXPORT void WKBundlePageForceRepaint(WKBundlePageRef page);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/Source/WebKit2/WebProcess/Plugins/PluginView.cpp b/Source/WebKit2/WebProcess/Plugins/PluginView.cpp
index f95df5f..3b1629d 100644
--- a/Source/WebKit2/WebProcess/Plugins/PluginView.cpp
+++ b/Source/WebKit2/WebProcess/Plugins/PluginView.cpp
@@ -533,7 +533,7 @@
         IntPoint documentOriginInWindowCoordinates = parent()->contentsToWindow(IntPoint());
         context->save();
         context->translate(-documentOriginInWindowCoordinates.x(), -documentOriginInWindowCoordinates.y());
-        m_plugin->paint(context, dirtyRect);
+        m_plugin->paint(context, paintRectInWindowCoordinates);
         context->restore();
     }
 }
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
index ceaa467..fce7730 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
@@ -1281,9 +1281,14 @@
     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
 }
 
-void WebPage::forceRepaint(uint64_t callbackID)
+void WebPage::forceRepaintWithoutCallback()
 {
     m_drawingArea->forceRepaint();
+}
+
+void WebPage::forceRepaint(uint64_t callbackID)
+{
+    forceRepaintWithoutCallback();
     send(Messages::WebPageProxy::VoidCallback(callbackID));
 }
 
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.h b/Source/WebKit2/WebProcess/WebPage/WebPage.h
index 0425114..c4cba3b 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPage.h
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.h
@@ -339,6 +339,8 @@
 
     void setMemoryCacheMessagesEnabled(bool);
 
+    void forceRepaintWithoutCallback();
+
 private:
     WebPage(uint64_t pageID, const WebPageCreationParameters&);
 
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index c503704..2c2a534 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,5 +1,41 @@
 2011-02-28  Adam Roben  <aroben@apple.com>
 
+        Add a test for the paint rect passed via WM_PAINT to windowless plugins
+
+        Test for <http://webkit.org/b/55365> <rdar://problem/9031089> REGRESSION (r79040): WebKit2:
+        Large portions of pages with plugins paint black
+
+        Reviewed by Anders Carlsson.
+
+        * DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp:
+        (PluginTest::NPP_HandleEvent):
+        * DumpRenderTree/TestNetscapePlugIn/PluginTest.h:
+        Added NPP_HandleEvent. Just returns 0 at this level.
+
+        * DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowlessPaintRectCoordinates.cpp: Added.
+        (WindowlessPaintRectCoordinates::WindowlessPaintRectCoordinates): Call up to the base class.
+        (WindowlessPaintRectCoordinates::NPP_New): Mark ourselves as windowless.
+        (WindowlessPaintRectCoordinates::NPP_HandleEvent): Check that the paint rect passed via
+        WM_PAINT has the expected coordinates.
+
+        * DumpRenderTree/TestNetscapePlugIn/main.cpp:
+        (NPP_HandleEvent): Give the PluginTest a chance to handle the event before doing anything
+        else.
+
+        * DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj: Added new file, let VS
+        resort things.
+
+        * WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
+        (WTR::InjectedBundlePage::didFinishLoadForFrame): Added a call to WKBundlePageForceRepaint.
+        This is roughly equivalent to the call to -[WebView displayIfNeeded] in -[FrameLoadDelegate
+        webView:didFinishLoadForFrame:] in DumpRenderTree.
+
+        * WebKitTestRunner/win/PlatformWebViewWin.cpp:
+        (WTR::PlatformWebView::PlatformWebView): Tell the WKView it's in a window so that plugins
+        can start running.
+
+2011-02-28  Adam Roben  <aroben@apple.com>
+
         Tell MiniBrowser's WKViews that they're in a window
 
         Fixes <http://webkit.org/b/55364> Plugins don't work in MiniBrowser on Windows
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp
index 90c9209..23120c4 100644
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp
+++ b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp
@@ -79,6 +79,11 @@
     return NPERR_NO_ERROR;
 }
 
+int16_t PluginTest::NPP_HandleEvent(void*)
+{
+    return 0;
+}
+
 void PluginTest::NPN_InvalidateRect(NPRect* invalidRect)
 {
     browser->invalidaterect(m_npp, invalidRect);
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h
index 0c5226a..7c3a53e 100644
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h
+++ b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h
@@ -60,6 +60,7 @@
     virtual NPError NPP_DestroyStream(NPStream* stream, NPReason reason);
     virtual NPError NPP_GetValue(NPPVariable, void* value);
     virtual NPError NPP_SetWindow(NPP, NPWindow*);
+    virtual int16_t NPP_HandleEvent(void* event);
 
     // NPN functions.
     NPError NPN_GetURL(const char* url, const char* target);
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowlessPaintRectCoordinates.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowlessPaintRectCoordinates.cpp
new file mode 100644
index 0000000..ffc92ea
--- /dev/null
+++ b/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/win/WindowlessPaintRectCoordinates.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "PluginTest.h"
+
+#include "PluginObject.h"
+
+using namespace std;
+
+// The rect passed in the WM_PAINT event for a windowless plugin should be relative to the page's
+// HWND and clipped to the plugin's bounds.
+
+class WindowlessPaintRectCoordinates : public PluginTest {
+public:
+    WindowlessPaintRectCoordinates(NPP, const string& identifier);
+
+private:
+    virtual NPError NPP_New(NPMIMEType, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData*);
+    virtual int16_t NPP_HandleEvent(void* event);
+};
+
+static PluginTest::Register<WindowlessPaintRectCoordinates> registrar("windowless-paint-rect-coordinates");
+
+WindowlessPaintRectCoordinates::WindowlessPaintRectCoordinates(NPP npp, const string& identifier)
+    : PluginTest(npp, identifier)
+{
+}
+
+NPError WindowlessPaintRectCoordinates::NPP_New(NPMIMEType, uint16_t, int16_t, char*[], char*[], NPSavedData*)
+{
+    browser->setvalue(m_npp, NPPVpluginWindowBool, 0);
+    return NPERR_NO_ERROR;
+}
+
+int16_t WindowlessPaintRectCoordinates::NPP_HandleEvent(void* typelessEvent)
+{
+    NPEvent* event = static_cast<NPEvent*>(typelessEvent);
+    if (!event) {
+        pluginLog(m_npp, "NPP_HandleEvent was passed a null event pointer");
+        return 0;
+    }
+
+    if (event->event != WM_PAINT)
+        return 0;
+
+    RECT* paintRect = reinterpret_cast<RECT*>(event->lParam);
+    if (!paintRect) {
+        pluginLog(m_npp, "A null paint rect was passed in the WM_PAINT event");
+        return 1;
+    }
+
+    // Keep these values in sync with windowless-paint-rect-coordinates.html.
+    RECT expectedRect = { 100, 100, 200, 200 };
+
+    if (::EqualRect(paintRect, &expectedRect))
+        pluginLog(m_npp, "Success");
+    else
+        pluginLog(m_npp, "Expected paint rect {left=%d, top=%d, right=%d, bottom=%d}, but got {left=%d, top=%d, right=%d, bottom=%d}", expectedRect.left, expectedRect.top, expectedRect.right, expectedRect.bottom, paintRect->left, paintRect->top, paintRect->right, paintRect->bottom);
+
+    return 1;
+}
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp
index 7635a09..b523fcb 100644
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp
+++ b/Tools/DumpRenderTree/TestNetscapePlugIn/main.cpp
@@ -697,6 +697,9 @@
 {
     PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
 
+    if (obj->pluginTest->NPP_HandleEvent(event) == 1)
+        return 1;
+
 #ifdef XP_MACOSX
 #ifndef NP_NO_CARBON
     if (obj->eventModel == NPEventModelCarbon)
diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj b/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj
index a3f1e8c..58a0a1f 100644
--- a/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj
+++ b/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj
@@ -398,11 +398,11 @@
 				>
 			</File>
 			<File
-				RelativePath="..\Tests\GetUserAgentWithNullNPPFromNPPNew.cpp"
+				RelativePath="..\Tests\GetURLWithJavaScriptURLDestroyingPlugin.cpp"
 				>
 			</File>
 			<File
-				RelativePath="..\Tests\GetURLWithJavaScriptURLDestroyingPlugin.cpp"
+				RelativePath="..\Tests\GetUserAgentWithNullNPPFromNPPNew.cpp"
 				>
 			</File>
 			<File
@@ -445,6 +445,10 @@
 					>
 				</File>
 				<File
+					RelativePath="..\Tests\win\WindowlessPaintRectCoordinates.cpp"
+					>
+				</File>
+				<File
 					RelativePath="..\Tests\win\WindowRegionIsSetToClipRect.cpp"
 					>
 				</File>
diff --git a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
index f1f4693..61e7761 100644
--- a/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
+++ b/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp
@@ -534,6 +534,8 @@
         return;
     InjectedBundle::shared().setTopLoadingFrame(0);
 
+    WKBundlePageForceRepaint(m_page);
+
     if (InjectedBundle::shared().layoutTestController()->waitToDump())
         return;
 
diff --git a/Tools/WebKitTestRunner/win/PlatformWebViewWin.cpp b/Tools/WebKitTestRunner/win/PlatformWebViewWin.cpp
index c132275..e75ccc8 100644
--- a/Tools/WebKitTestRunner/win/PlatformWebViewWin.cpp
+++ b/Tools/WebKitTestRunner/win/PlatformWebViewWin.cpp
@@ -54,6 +54,7 @@
     RECT viewRect = {0, 0, 800, 600};
     m_window = CreateWindowExW(0, hostWindowClassName, L"WebKitTestRunner", WS_OVERLAPPEDWINDOW, 0 /*XOFFSET*/, 0 /*YOFFSET*/, viewRect.right, viewRect.bottom, 0, 0, GetModuleHandle(0), 0);
     m_view = WKViewCreate(viewRect, contextRef, pageGroupRef, m_window);
+    WKViewSetIsInWindow(m_view, true);
 }
 
 PlatformWebView::~PlatformWebView()