Changeset 40366 in webkit
- Timestamp:
- Jan 29, 2009, 11:21:07 AM (18 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
-
WebCore/ChangeLog (modified) (1 diff)
-
WebCore/platform/graphics/GraphicsContext.h (modified) (1 diff)
-
WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h (modified) (2 diffs)
-
WebCore/platform/graphics/win/GraphicsContextCGWin.cpp (modified) (1 diff)
-
WebCore/plugins/PluginView.cpp (modified) (1 diff)
-
WebCore/plugins/PluginView.h (modified) (2 diffs)
-
WebCore/plugins/win/PluginViewWin.cpp (modified) (5 diffs)
-
WebKit/win/ChangeLog (modified) (1 diff)
-
WebKit/win/WebFrame.cpp (modified) (2 diffs)
-
WebKit/win/WebView.cpp (modified) (8 diffs)
-
WebKit/win/WebView.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r40364 r40366 1 2009-01-29 Adam Roben <aroben@apple.com> 2 3 Fix Bug 23623: Windowed Flash instances aren't captured when a WebView 4 receives a WM_PRINTCLIENT message 5 6 <https://bugs.webkit.org/show_bug.cgi?id=23623> 7 <rdar://problem/6513921> 8 <rdar://problem/6536874> 9 10 Flash doesn't seem to respond to WM_PRINTCLIENT, so we change 11 WM_PRINTCLIENT messages into WM_PAINT messages and hook into the 12 BeginPaint/EndPaint APIs to return the HDC we received from 13 WM_PRINTCLIENT. This causes the plugin to paint into the 14 WM_PRINTCLIENT HDC via its normal WM_PAINT handler. This technique 15 came from <http://www.fengyuan.com/article/wmprint.html>. 16 17 No test possible. 18 19 Reviewed by Darin Adler. 20 21 * platform/graphics/GraphicsContext.h: Added 22 [set]ShouldIncludeChildWindows on Windows. 23 24 * platform/graphics/cg/GraphicsContextPlatformPrivateCG.h: Added 25 m_shouldIncludeChildWindows. 26 (WebCore::GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate): 27 Initialize the new member. 28 29 * platform/graphics/win/GraphicsContextCGWin.cpp: 30 (WebCore::GraphicsContext::setShouldIncludeChildWindows): 31 (WebCore::GraphicsContext::shouldIncludeChildWindows): 32 Added simple setter and getter. 33 34 * plugins/PluginView.cpp: 35 (WebCore::PluginView::PluginView): Initialize the new member. 36 37 * plugins/PluginView.h: Added m_wmPrintHDC and various functions 38 required for making WM_PRINTCLIENT work. 39 40 * plugins/win/PluginViewWin.cpp: 41 (WebCore::PluginView::hookedBeginPaint): 42 (WebCore::PluginView::hookedEndPaint): 43 (WebCore::hook): 44 (WebCore::setUpOffscreenPaintingHooks): 45 Added. Code was modified from code available on fengyuan.com. 46 47 (WebCore::PluginView::wndProc): Turn WM_PRINTCLIENT messages into 48 WM_PAINT messages and save off the HDC that we're supposed to paint 49 into. 50 51 (WebCore::PluginView::paintWindowedPluginIntoContext): Added. Gets an 52 HDC from the GraphicsContext, translates it into client coordinates, 53 gets the plugin to draw into the HDC by sending a WM_PRINTCLIENT 54 message, and returns the HDC to the GraphicsContext. 55 56 (WebCore::PluginView::paint): If we're trying to paint a windowed 57 plugin into the GraphicsContext, call paintWindowedPluginIntoContext. 58 59 (WebCore::PluginView::init): Call setUpOffscreenPaintingHooks to make 60 our WM_PRINTCLIENT trick work. 61 1 62 2009-01-29 David Hyatt <hyatt@apple.com> 2 63 -
trunk/WebCore/platform/graphics/GraphicsContext.h
r40292 r40366 273 273 void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend = true, bool mayCreateBitmap = true); // The passed in HDC should be the one handed back by getWindowsContext. 274 274 275 // When set to true, child windows should be rendered into this context 276 // rather than allowing them just to render to the screen. Defaults to 277 // false. 278 // FIXME: This is a layering violation. GraphicsContext shouldn't know 279 // what a "window" is. It would be much more appropriate for this flag 280 // to be passed as a parameter alongside the GraphicsContext, but doing 281 // that would require lots of changes in cross-platform code that we 282 // aren't sure we want to make. 283 void setShouldIncludeChildWindows(bool); 284 bool shouldIncludeChildWindows() const; 285 275 286 class WindowsBitmap : public Noncopyable { 276 287 public: -
trunk/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h
r39635 r40366 35 35 , m_hdc(0) 36 36 , m_transparencyCount(0) 37 , m_shouldIncludeChildWindows(false) 37 38 #endif 38 39 , m_userToDeviceTransformKnownToBeIdentity(false) … … 75 76 HDC m_hdc; 76 77 unsigned m_transparencyCount; 78 bool m_shouldIncludeChildWindows; 77 79 #endif 78 80 -
trunk/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
r39635 r40366 174 174 } 175 175 176 void GraphicsContext::setShouldIncludeChildWindows(bool include) 177 { 178 m_data->m_shouldIncludeChildWindows = include; 179 } 180 181 bool GraphicsContext::shouldIncludeChildWindows() const 182 { 183 return m_data->m_shouldIncludeChildWindows; 184 } 185 176 186 GraphicsContext::WindowsBitmap::WindowsBitmap(HDC hdc, IntSize size) 177 187 : m_hdc(0) -
trunk/WebCore/plugins/PluginView.cpp
r40196 r40366 566 566 , m_lastMessage(0) 567 567 , m_isCallingPluginWndProc(false) 568 , m_wmPrintHDC(0) 568 569 #endif 569 570 #if (PLATFORM(QT) && PLATFORM(WIN_OS)) || defined(XP_MACOSX) -
trunk/WebCore/plugins/PluginView.h
r39616 r40366 208 208 209 209 void invalidateWindowlessPluginRect(const IntRect&); 210 210 211 #if PLATFORM(WIN_OS) && !PLATFORM(WX) && ENABLE(NETSCAPE_PLUGIN_API) 212 void paintWindowedPluginIntoContext(GraphicsContext*, const IntRect&) const; 213 static HDC WINAPI hookedBeginPaint(HWND, PAINTSTRUCT*); 214 static BOOL WINAPI hookedEndPaint(HWND, const PAINTSTRUCT*); 215 #endif 216 211 217 Frame* m_parentFrame; 212 218 RefPtr<PluginPackage> m_plugin; … … 271 277 unsigned m_lastMessage; 272 278 bool m_isCallingPluginWndProc; 279 HDC m_wmPrintHDC; 273 280 #endif 274 281 -
trunk/WebCore/plugins/win/PluginViewWin.cpp
r39238 r40366 100 100 static const char* MozillaUserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0"; 101 101 102 // The code used to hook BeginPaint/EndPaint originally came from 103 // <http://www.fengyuan.com/article/wmprint.html>. 104 // Copyright (C) 2000 by Feng Yuan (www.fengyuan.com). 105 106 static unsigned beginPaintSysCall; 107 static BYTE* beginPaint; 108 109 static unsigned endPaintSysCall; 110 static BYTE* endPaint; 111 112 HDC WINAPI PluginView::hookedBeginPaint(HWND hWnd, PAINTSTRUCT* lpPaint) 113 { 114 PluginView* pluginView = reinterpret_cast<PluginView*>(GetProp(hWnd, kWebPluginViewProperty)); 115 if (pluginView && pluginView->m_wmPrintHDC) { 116 // We're secretly handling WM_PRINTCLIENT, so set up the PAINTSTRUCT so 117 // that the plugin will paint into the HDC we provide. 118 memset(lpPaint, 0, sizeof(PAINTSTRUCT)); 119 lpPaint->hdc = pluginView->m_wmPrintHDC; 120 GetClientRect(hWnd, &lpPaint->rcPaint); 121 return pluginView->m_wmPrintHDC; 122 } 123 124 // Call through to the original BeginPaint. 125 __asm mov eax, beginPaintSysCall 126 __asm push lpPaint 127 __asm push hWnd 128 __asm call beginPaint 129 } 130 131 BOOL WINAPI PluginView::hookedEndPaint(HWND hWnd, const PAINTSTRUCT* lpPaint) 132 { 133 PluginView* pluginView = reinterpret_cast<PluginView*>(GetProp(hWnd, kWebPluginViewProperty)); 134 if (pluginView && pluginView->m_wmPrintHDC) { 135 // We're secretly handling WM_PRINTCLIENT, so we don't have to do any 136 // cleanup. 137 return TRUE; 138 } 139 140 // Call through to the original EndPaint. 141 __asm mov eax, endPaintSysCall 142 __asm push lpPaint 143 __asm push hWnd 144 __asm call endPaint 145 } 146 147 static void hook(const char* module, const char* proc, unsigned& sysCallID, BYTE*& pProc, const void* pNewProc) 148 { 149 // See <http://www.fengyuan.com/article/wmprint.html> for an explanation of 150 // how this function works. 151 152 HINSTANCE hMod = GetModuleHandleA(module); 153 154 pProc = reinterpret_cast<BYTE*>(GetProcAddress(hMod, proc)); 155 156 if (pProc[0] != 0xB8) 157 return; 158 159 // FIXME: Should we be reading the bytes one-by-one instead of doing an 160 // unaligned read? 161 sysCallID = *reinterpret_cast<unsigned*>(pProc + 1); 162 163 DWORD flOldProtect; 164 if (!VirtualProtect(pProc, 5, PAGE_EXECUTE_READWRITE, &flOldProtect)) 165 return; 166 167 pProc[0] = 0xE9; 168 *reinterpret_cast<unsigned*>(pProc + 1) = reinterpret_cast<intptr_t>(pNewProc) - reinterpret_cast<intptr_t>(pProc + 5); 169 170 pProc += 5; 171 } 172 173 static void setUpOffscreenPaintingHooks(HDC (WINAPI*hookedBeginPaint)(HWND, PAINTSTRUCT*), BOOL (WINAPI*hookedEndPaint)(HWND, const PAINTSTRUCT*)) 174 { 175 static bool haveHooked = false; 176 if (haveHooked) 177 return; 178 haveHooked = true; 179 180 // Most (all?) windowed plugins don't seem to respond to WM_PRINTCLIENT, so 181 // we hook into BeginPaint/EndPaint to allow their normal WM_PAINT handling 182 // to draw into a given HDC. Note that this hooking affects the entire 183 // process. 184 hook("user32.dll", "BeginPaint", beginPaintSysCall, beginPaint, hookedBeginPaint); 185 hook("user32.dll", "EndPaint", endPaintSysCall, endPaint, hookedEndPaint); 186 } 187 102 188 static bool registerPluginView() 103 189 { … … 202 288 } 203 289 290 if (message == WM_PRINTCLIENT) { 291 // Most (all?) windowed plugins don't respond to WM_PRINTCLIENT, so we 292 // change the message to WM_PAINT and rely on our hooked versions of 293 // BeginPaint/EndPaint to make the plugin draw into the given HDC. 294 message = WM_PAINT; 295 m_wmPrintHDC = reinterpret_cast<HDC>(wParam); 296 } 297 204 298 // Call the plug-in's window proc. 205 299 LRESULT result = ::CallWindowProc(m_pluginWndProc, hWnd, message, wParam, lParam); 300 301 m_wmPrintHDC = 0; 206 302 207 303 m_isCallingPluginWndProc = false; … … 306 402 } 307 403 404 void PluginView::paintWindowedPluginIntoContext(GraphicsContext* context, const IntRect& rect) const 405 { 406 ASSERT(m_isWindowed); 407 ASSERT(context->shouldIncludeChildWindows()); 408 409 ASSERT(parent()->isFrameView()); 410 IntPoint locationInWindow = static_cast<FrameView*>(parent())->contentsToWindow(frameRect().location()); 411 412 HDC hdc = context->getWindowsContext(frameRect(), false); 413 414 XFORM originalTransform; 415 GetWorldTransform(hdc, &originalTransform); 416 417 // The plugin expects the DC to be in client coordinates, so we translate 418 // the DC to make that so. 419 XFORM transform = originalTransform; 420 transform.eDx = locationInWindow.x(); 421 transform.eDy = locationInWindow.y(); 422 423 SetWorldTransform(hdc, &transform); 424 425 SendMessage(platformPluginWidget(), WM_PRINTCLIENT, reinterpret_cast<WPARAM>(hdc), PRF_CLIENT | PRF_CHILDREN | PRF_OWNED); 426 427 SetWorldTransform(hdc, &originalTransform); 428 429 context->releaseWindowsContext(hdc, frameRect(), false); 430 } 431 308 432 void PluginView::paint(GraphicsContext* context, const IntRect& rect) 309 433 { … … 314 438 } 315 439 316 if (m_isWindowed || context->paintingDisabled()) 317 return; 440 if (context->paintingDisabled()) 441 return; 442 443 if (m_isWindowed) { 444 if (context->shouldIncludeChildWindows()) 445 paintWindowedPluginIntoContext(context, rect); 446 return; 447 } 318 448 319 449 ASSERT(parent()->isFrameView()); … … 801 931 if (m_isWindowed) { 802 932 registerPluginView(); 933 setUpOffscreenPaintingHooks(hookedBeginPaint, hookedEndPaint); 803 934 804 935 DWORD flags = WS_CHILD; -
trunk/WebKit/win/ChangeLog
r40365 r40366 1 2009-01-29 Adam Roben <aroben@apple.com> 2 3 Fix Bug 23623: Windowed Flash instances aren't captured when a WebView 4 receives a WM_PRINTCLIENT message 5 6 <https://bugs.webkit.org/show_bug.cgi?id=23623> 7 <rdar://problem/6513921> 8 <rdar://problem/6536874> 9 10 Reviewed by Darin Adler. 11 12 * WebFrame.cpp: 13 (WebFrame::paintDocumentRectToContext): 14 (WebFrame::spoolPages): 15 Call GraphicsContext::setShouldIncludeChildWindows so that child 16 windows will be painted into the GraphicsContext rather than painted 17 directly to the screen. 18 19 * WebView.cpp: 20 (WebView::updateBackingStore): Added a windowsToPaint parameter, which 21 we pass along to paintIntoBackingStore. 22 23 (WebView::paint): Tell updateBackingStore to paint child windows if 24 we're not painting to the screen. 25 26 (WebView::paintIntoBackingStore): Added a windowsToPaint paramter, 27 which we use to tell our GraphicsContext whether or not to include 28 child windows. 29 30 * WebView.h: Added windowsToPaint parameters to paintIntoBackingStore 31 and updateBackingStore (which I also made private). 32 1 33 2009-01-29 Adam Roben <aroben@apple.com> 2 34 -
trunk/WebKit/win/WebFrame.cpp
r40289 r40366 314 314 HDC dc = (HDC)(ULONG64)deviceContext; 315 315 GraphicsContext gc(dc); 316 gc.setShouldIncludeChildWindows(true); 316 317 gc.save(); 317 318 LONG width = rect.right - rect.left; … … 1813 1814 headerAndFooterHeights(&headerHeight, &footerHeight); 1814 1815 GraphicsContext spoolCtx(pctx); 1816 spoolCtx.setShouldIncludeChildWindows(true); 1815 1817 1816 1818 for (UINT ii = startPage; ii < endPage; ii++) { -
trunk/WebKit/win/WebView.cpp
r40353 r40366 820 820 } 821 821 822 void WebView::updateBackingStore(FrameView* frameView, HDC dc, bool backingStoreCompletelyDirty )822 void WebView::updateBackingStore(FrameView* frameView, HDC dc, bool backingStoreCompletelyDirty, WindowsToPaint windowsToPaint) 823 823 { 824 824 LOCAL_GDI_COUNTER(0, __FUNCTION__); … … 850 850 851 851 for (unsigned i = 0; i < paintRects.size(); ++i) 852 paintIntoBackingStore(frameView, bitmapDC, paintRects[i] );852 paintIntoBackingStore(frameView, bitmapDC, paintRects[i], windowsToPaint); 853 853 854 854 if (m_uiDelegatePrivate) { … … 885 885 int regionType = NULLREGION; 886 886 PAINTSTRUCT ps; 887 WindowsToPaint windowsToPaint; 887 888 if (!dc) { 888 889 region.set(CreateRectRgn(0,0,0,0)); … … 890 891 hdc = BeginPaint(m_viewWindow, &ps); 891 892 rcPaint = ps.rcPaint; 893 // We're painting to the screen, and our child windows can handle 894 // painting themselves to the screen. 895 windowsToPaint = PaintWebViewOnly; 892 896 } else { 893 897 hdc = dc; … … 895 899 if (options & PRF_ERASEBKGND) 896 900 ::FillRect(hdc, &rcPaint, (HBRUSH)GetStockObject(WHITE_BRUSH)); 901 // Since we aren't painting to the screen, we want to paint all our 902 // children into the HDC. 903 windowsToPaint = PaintWebViewAndChildren; 897 904 } 898 905 … … 902 909 903 910 // Update our backing store if needed. 904 updateBackingStore(frameView, bitmapDC, backingStoreCompletelyDirty );911 updateBackingStore(frameView, bitmapDC, backingStoreCompletelyDirty, windowsToPaint); 905 912 906 913 // Now we blit the updated backing store … … 943 950 } 944 951 945 void WebView::paintIntoBackingStore(FrameView* frameView, HDC bitmapDC, const IntRect& dirtyRect )952 void WebView::paintIntoBackingStore(FrameView* frameView, HDC bitmapDC, const IntRect& dirtyRect, WindowsToPaint windowsToPaint) 946 953 { 947 954 LOCAL_GDI_COUNTER(0, __FUNCTION__); … … 960 967 961 968 GraphicsContext gc(bitmapDC, m_transparent); 969 gc.setShouldIncludeChildWindows(windowsToPaint == PaintWebViewAndChildren); 962 970 gc.save(); 963 971 if (m_transparent) -
trunk/WebKit/win/WebView.h
r39757 r40366 744 744 bool inResizer(LPARAM lParam); 745 745 void paint(HDC, LPARAM); 746 void paintIntoBackingStore(WebCore::FrameView*, HDC bitmapDC, const WebCore::IntRect& dirtyRect);747 746 void paintIntoWindow(HDC bitmapDC, HDC windowDC, const WebCore::IntRect& dirtyRect); 748 747 bool ensureBackingStore(); … … 750 749 void addToDirtyRegion(HRGN); 751 750 void scrollBackingStore(WebCore::FrameView*, int dx, int dy, const WebCore::IntRect& scrollViewRect, const WebCore::IntRect& clipRect); 752 void updateBackingStore(WebCore::FrameView*, HDC = 0, bool backingStoreCompletelyDirty = false);753 751 void deleteBackingStore(); 754 752 void repaint(const WebCore::IntRect&, bool contentChanged, bool immediate = false, bool repaintContentOnly = false); … … 826 824 HRESULT resetZoom(bool isTextOnly); 827 825 bool active(); 826 827 enum WindowsToPaint { PaintWebViewOnly, PaintWebViewAndChildren }; 828 void paintIntoBackingStore(WebCore::FrameView*, HDC bitmapDC, const WebCore::IntRect& dirtyRect, WindowsToPaint); 829 void updateBackingStore(WebCore::FrameView*, HDC = 0, bool backingStoreCompletelyDirty = false, WindowsToPaint = PaintWebViewOnly); 828 830 829 831 protected:
Note:
See TracChangeset
for help on using the changeset viewer.