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.
authorJim Mathies <jmathies@mozilla.com>
Mon, 06 Dec 2010 18:50:56 -0600
changeset 58736 fb8ad78374dfbac4438a05249b4f767160adcf9f
parent 58735 038591612c97ce8fe812a807a180097e1435f1f7
child 58737 07e02bc22afb8bd9c74200a1badf7a8e460e44fc
push id17411
push userjmathies@mozilla.com
push dateTue, 07 Dec 2010 00:51:10 +0000
treeherdermozilla-central@fb8ad78374df [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent, betaN
bugs604303, 130078
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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.
dom/plugins/PluginModuleChild.cpp
dom/plugins/PluginModuleChild.h
--- 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;
     }