diff options
Diffstat (limited to 'WebCore/plugins/win/PluginViewWin.cpp')
-rw-r--r-- | WebCore/plugins/win/PluginViewWin.cpp | 145 |
1 files changed, 89 insertions, 56 deletions
diff --git a/WebCore/plugins/win/PluginViewWin.cpp b/WebCore/plugins/win/PluginViewWin.cpp index 0da4402..ccbf6f8 100644 --- a/WebCore/plugins/win/PluginViewWin.cpp +++ b/WebCore/plugins/win/PluginViewWin.cpp @@ -29,6 +29,7 @@ #include "PluginView.h" +#include "BitmapImage.h" #include "Document.h" #include "DocumentLoader.h" #include "Element.h" @@ -52,6 +53,7 @@ #include "PluginMessageThrottlerWin.h" #include "PluginPackage.h" #include "PluginMainThreadScheduler.h" +#include "RenderWidget.h" #include "JSDOMBinding.h" #include "ScriptController.h" #include "PluginDatabase.h" @@ -74,17 +76,17 @@ #endif #if PLATFORM(QT) -#include <QWidget.h> +#include "QWebPageClient.h" #endif -static inline HWND windowHandleForPlatformWidget(PlatformWidget widget) +static inline HWND windowHandleForPageClient(PlatformPageClient client) { #if PLATFORM(QT) - if (!widget) + if (!client) return 0; - return widget->winId(); + return client->winId(); #else - return widget; + return client; #endif } @@ -115,6 +117,14 @@ static BYTE* beginPaint; static unsigned endPaintSysCall; static BYTE* endPaint; +typedef HDC (WINAPI *PtrBeginPaint)(HWND, PAINTSTRUCT*); +typedef BOOL (WINAPI *PtrEndPaint)(HWND, const PAINTSTRUCT*); + +#if PLATFORM(WIN_OS) && PLATFORM(X86_64) && COMPILER(MSVC) +extern "C" HDC __stdcall _HBeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint); +extern "C" BOOL __stdcall _HEndPaint(HWND hWnd, const PAINTSTRUCT* lpPaint); +#endif + HDC WINAPI PluginView::hookedBeginPaint(HWND hWnd, PAINTSTRUCT* lpPaint) { PluginView* pluginView = reinterpret_cast<PluginView*>(GetProp(hWnd, kWebPluginViewProperty)); @@ -137,12 +147,14 @@ HDC WINAPI PluginView::hookedBeginPaint(HWND hWnd, PAINTSTRUCT* lpPaint) : "memory" ); return result; -#else +#elif defined(_M_IX86) // Call through to the original BeginPaint. __asm mov eax, beginPaintSysCall __asm push lpPaint __asm push hWnd __asm call beginPaint +#else + return _HBeginPaint(hWnd, lpPaint); #endif } @@ -164,12 +176,14 @@ BOOL WINAPI PluginView::hookedEndPaint(HWND hWnd, const PAINTSTRUCT* lpPaint) : "a" (endPaintSysCall), "g" (lpPaint), "g" (hWnd), "m" (*endPaint) ); return result; -#else +#elif defined (_M_IX86) // Call through to the original EndPaint. __asm mov eax, endPaintSysCall __asm push lpPaint __asm push hWnd __asm call endPaint +#else + return _HEndPaint(hWnd, lpPaint); #endif } @@ -182,6 +196,7 @@ static void hook(const char* module, const char* proc, unsigned& sysCallID, BYTE pProc = reinterpret_cast<BYTE*>(reinterpret_cast<ptrdiff_t>(GetProcAddress(hMod, proc))); +#if COMPILER(GCC) || defined(_M_IX86) if (pProc[0] != 0xB8) return; @@ -197,6 +212,35 @@ static void hook(const char* module, const char* proc, unsigned& sysCallID, BYTE *reinterpret_cast<unsigned*>(pProc + 1) = reinterpret_cast<intptr_t>(pNewProc) - reinterpret_cast<intptr_t>(pProc + 5); pProc += 5; +#else + /* Disassembly of BeginPaint() + 00000000779FC5B0 4C 8B D1 mov r10,rcx + 00000000779FC5B3 B8 17 10 00 00 mov eax,1017h + 00000000779FC5B8 0F 05 syscall + 00000000779FC5BA C3 ret + 00000000779FC5BB 90 nop + 00000000779FC5BC 90 nop + 00000000779FC5BD 90 nop + 00000000779FC5BE 90 nop + 00000000779FC5BF 90 nop + 00000000779FC5C0 90 nop + 00000000779FC5C1 90 nop + 00000000779FC5C2 90 nop + 00000000779FC5C3 90 nop + */ + // Check for the signature as in the above disassembly + DWORD guard = 0xB8D18B4C; + if (*reinterpret_cast<DWORD*>(pProc) != guard) + return; + + DWORD flOldProtect; + VirtualProtect(pProc, 12, PAGE_EXECUTE_READWRITE, & flOldProtect); + pProc[0] = 0x48; // mov rax, this + pProc[1] = 0xb8; + *(__int64*)(pProc+2) = (__int64)pNewProc; + pProc[10] = 0xff; // jmp rax + pProc[11] = 0xe0; +#endif } static void setUpOffscreenPaintingHooks(HDC (WINAPI*hookedBeginPaint)(HWND, PAINTSTRUCT*), BOOL (WINAPI*hookedEndPaint)(HWND, const PAINTSTRUCT*)) @@ -838,7 +882,7 @@ NPError PluginView::getValue(NPNVariable variable, void* value) case NPNVnetscapeWindow: { HWND* w = reinterpret_cast<HWND*>(value); - *w = windowHandleForPlatformWidget(parent() ? parent()->hostWindow()->platformWindow() : 0); + *w = windowHandleForPageClient(parent() ? parent()->hostWindow()->platformPageClient() : 0); return NPERR_NO_ERROR; } @@ -910,55 +954,10 @@ void PluginView::forceRedraw() if (m_isWindowed) ::UpdateWindow(platformPluginWidget()); else - ::UpdateWindow(windowHandleForPlatformWidget(parent() ? parent()->hostWindow()->platformWindow() : 0)); -} - -PluginView::~PluginView() -{ - removeFromUnstartedListIfNecessary(); - - stop(); - - deleteAllValues(m_requests); - - freeStringArray(m_paramNames, m_paramCount); - freeStringArray(m_paramValues, m_paramCount); - - if (platformPluginWidget()) - DestroyWindow(platformPluginWidget()); - - m_parentFrame->script()->cleanupScriptObjectsForPlugin(this); - - if (m_plugin && !m_plugin->quirks().contains(PluginQuirkDontUnloadPlugin)) - m_plugin->unload(); + ::UpdateWindow(windowHandleForPageClient(parent() ? parent()->hostWindow()->platformPageClient() : 0)); } -void PluginView::init() -{ - if (m_haveInitialized) - return; - m_haveInitialized = true; - - if (!m_plugin) { - ASSERT(m_status == PluginStatusCanNotFindPlugin); - return; - } - - if (!m_plugin->load()) { - m_plugin = 0; - m_status = PluginStatusCanNotLoadPlugin; - return; - } - - if (!startOrAddToUnstartedList()) { - m_status = PluginStatusCanNotLoadPlugin; - return; - } - - m_status = PluginStatusLoadedSuccessfully; -} - -void PluginView::platformStart() +bool PluginView::platformStart() { ASSERT(m_isStarted); ASSERT(m_status == PluginStatusLoadedSuccessfully); @@ -973,7 +972,7 @@ void PluginView::platformStart() if (isSelfVisible()) flags |= WS_VISIBLE; - HWND parentWindowHandle = windowHandleForPlatformWidget(m_parentFrame->view()->hostWindow()->platformWindow()); + HWND parentWindowHandle = windowHandleForPageClient(m_parentFrame->view()->hostWindow()->platformPageClient()); HWND window = ::CreateWindowEx(0, kWebPluginViewdowClassName, 0, flags, 0, 0, 0, 0, parentWindowHandle, 0, Page::instanceHandle(), 0); @@ -1005,6 +1004,40 @@ void PluginView::platformStart() if (!m_plugin->quirks().contains(PluginQuirkDeferFirstSetWindowCall)) setNPWindowRect(frameRect()); + + return true; +} + +void PluginView::platformDestroy() +{ + if (!platformPluginWidget()) + return; + + DestroyWindow(platformPluginWidget()); + setPlatformPluginWidget(0); +} + +void PluginView::halt() +{ +#if !PLATFORM(QT) + // Show a screenshot of the plug-in. + OwnPtr<HBITMAP> nodeImage(m_parentFrame->nodeImage(m_element)); + toRenderWidget(m_element->renderer())->showSubstituteImage(BitmapImage::create(nodeImage.get())); +#endif + + stop(); + platformDestroy(); +} + +void PluginView::restart() +{ + ASSERT(!m_isStarted); + + // Clear any substitute image. + toRenderWidget(m_element->renderer())->showSubstituteImage(0); + + m_haveUpdatedPluginWidget = false; + start(); } } // namespace WebCore |