summaryrefslogtreecommitdiffstats
path: root/WebCore/plugins/win/PluginViewWin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/plugins/win/PluginViewWin.cpp')
-rw-r--r--WebCore/plugins/win/PluginViewWin.cpp145
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