Bug 604303 - Trap GetWindowInfo calls in flash and return browser window metrics similar to what we returned prior to the landing of
bug 130078. r=bent, a=betaN.
--- a/dom/plugins/PluginModuleChild.cpp
+++ b/dom/plugins/PluginModuleChild.cpp
@@ -65,42 +65,49 @@
#include "mozilla/plugins/BrowserStreamChild.h"
#include "mozilla/plugins/PluginStreamChild.h"
#include "PluginIdentifierChild.h"
#include "nsNPAPIPlugin.h"
#ifdef XP_WIN
#include "COMMessageFilter.h"
+#include "nsWindowsDllInterceptor.h"
#endif
#ifdef OS_MACOSX
#include "PluginInterposeOSX.h"
#include "PluginUtilsOSX.h"
#endif
using namespace mozilla::plugins;
#if defined(XP_WIN)
const PRUnichar * kFlashFullscreenClass = L"ShockwaveFlashFullScreen";
+const PRUnichar * kMozillaWindowClass = L"MozillaWindowClass";
#endif
namespace {
PluginModuleChild* gInstance = nsnull;
}
#ifdef MOZ_WIDGET_QT
typedef void (*_gtk_init_fn)(int argc, char **argv);
static _gtk_init_fn s_gtk_init = nsnull;
static PRLibrary *sGtkLib = nsnull;
#endif
#ifdef XP_WIN
// Used with fix for flash fullscreen window loosing focus.
static bool gDelayFlashFocusReplyUntilEval = false;
+// Used to fix GetWindowInfo problems with internal flash settings dialogs
+static WindowsDllInterceptor sUser32Intercept;
+typedef BOOL (WINAPI *GetWindowInfoPtr)(HWND hwnd, PWINDOWINFO pwi);
+static GetWindowInfoPtr sGetWindowInfoPtrStub = NULL;
+static HWND sBrowserHwnd = NULL;
#endif
PluginModuleChild::PluginModuleChild() :
mLibrary(0),
mShutdownFunc(0),
mInitializeFunc(0),
mQuirks(QUIRKS_NOT_INITIALIZED)
#if defined(OS_WIN) || defined(OS_MACOSX)
@@ -1705,28 +1712,66 @@ PluginModuleChild::AllocPPluginIdentifie
bool
PluginModuleChild::DeallocPPluginIdentifier(PPluginIdentifierChild* aActor)
{
delete aActor;
return true;
}
+#if defined(XP_WIN)
+BOOL WINAPI
+PMCGetWindowInfoHook(HWND hWnd, PWINDOWINFO pwi)
+{
+ if (!pwi)
+ return FALSE;
+
+ if (!sGetWindowInfoPtrStub) {
+ NS_ASSERTION(FALSE, "Something is horribly wrong in PMCGetWindowInfoHook!");
+ return FALSE;
+ }
+
+ if (!sBrowserHwnd) {
+ PRUnichar szClass[20];
+ if (GetClassNameW(hWnd, szClass, NS_ARRAY_LENGTH(szClass)) &&
+ !wcscmp(szClass, kMozillaWindowClass)) {
+ sBrowserHwnd = hWnd;
+ }
+ }
+ // Oddity: flash does strange rect comparisons for mouse input destined for
+ // it's internal settings window. Post removing sub widgets for tabs, touch
+ // this up so they get the rect they expect.
+ // XXX potentially tie this to a specific major version?
+ BOOL result = sGetWindowInfoPtrStub(hWnd, pwi);
+ if (sBrowserHwnd && sBrowserHwnd == hWnd)
+ pwi->rcWindow = pwi->rcClient;
+ return result;
+}
+#endif
+
PPluginInstanceChild*
PluginModuleChild::AllocPPluginInstance(const nsCString& aMimeType,
const uint16_t& aMode,
const InfallibleTArray<nsCString>& aNames,
const InfallibleTArray<nsCString>& aValues,
NPError* rv)
{
PLUGIN_LOG_DEBUG_METHOD;
AssertPluginThread();
InitQuirksModes(aMimeType);
+#ifdef XP_WIN
+ if (mQuirks & QUIRK_FLASH_HOOK_GETWINDOINFO) {
+ sUser32Intercept.Init("user32.dll");
+ sUser32Intercept.AddHook("GetWindowInfo", PMCGetWindowInfoHook,
+ (void**) &sGetWindowInfoPtrStub);
+ }
+#endif
+
nsAutoPtr<PluginInstanceChild> childInstance(
new PluginInstanceChild(&mFunctions));
if (!childInstance->Initialize()) {
*rv = NPERR_GENERIC_ERROR;
return 0;
}
return childInstance.forget();
}
@@ -1749,16 +1794,17 @@ PluginModuleChild::InitQuirksModes(const
#ifdef OS_WIN
// application/x-shockwave-flash
NS_NAMED_LITERAL_CSTRING(flash, "application/x-shockwave-flash");
if (FindInReadable(flash, aMimeType)) {
mQuirks |= QUIRK_WINLESS_TRACKPOPUP_HOOK;
mQuirks |= QUIRK_FLASH_THROTTLE_WMUSER_EVENTS;
mQuirks |= QUIRK_FLASH_HOOK_SETLONGPTR;
+ mQuirks |= QUIRK_FLASH_HOOK_GETWINDOINFO;
}
#endif
}
bool
PluginModuleChild::AnswerPPluginInstanceConstructor(PPluginInstanceChild* aActor,
const nsCString& aMimeType,
const uint16_t& aMode,
--- a/dom/plugins/PluginModuleChild.h
+++ b/dom/plugins/PluginModuleChild.h
@@ -220,16 +220,20 @@ public:
// processing lag.
QUIRK_FLASH_THROTTLE_WMUSER_EVENTS = 1 << 2,
// Win32: Catch resets on our subclass by hooking SetWindowLong.
QUIRK_FLASH_HOOK_SETLONGPTR = 1 << 3,
// X11: Work around a bug in Flash up to 10.1 d51 at least, where
// expose event top left coordinates within the plugin-rect and
// not at the drawable origin are misinterpreted.
QUIRK_FLASH_EXPOSE_COORD_TRANSLATION = 1 << 4,
+ // Win32: Catch get window info calls on the browser and tweak the
+ // results so mouse input works when flash is displaying it's settings
+ // window.
+ QUIRK_FLASH_HOOK_GETWINDOINFO = 1 << 5,
};
int GetQuirks() { return mQuirks; }
void AddQuirk(PluginQuirks quirk) {
if (mQuirks == QUIRKS_NOT_INITIALIZED)
mQuirks = 0;
mQuirks |= quirk;
}