Bug 531551 - fix for crashes with older acrobat versions. r=jimm, a=blocking-final.
authorJim Mathies <jmathies@mozilla.com>
Tue, 07 Sep 2010 11:12:28 -0500
changeset 52098 5da673421ec0
parent 52097 3db393b691be
child 52099 232553f741a0
push id15541
push userjmathies@mozilla.com
push date2010-09-07 16:13 +0000
treeherdermozilla-central@5da673421ec0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm, blocking-final
bugs531551
milestone2.0b6pre
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 531551 - fix for crashes with older acrobat versions. r=jimm, a=blocking-final.
modules/plugin/base/src/nsPluginNativeWindowWin.cpp
--- a/modules/plugin/base/src/nsPluginNativeWindowWin.cpp
+++ b/modules/plugin/base/src/nsPluginNativeWindowWin.cpp
@@ -127,16 +127,17 @@ void PluginWindowEvent::Init(const Plugi
 /**
  *  nsPluginNativeWindow Windows specific class declaration
  */
 
 typedef enum {
   nsPluginType_Unknown = 0,
   nsPluginType_Flash,
   nsPluginType_Real,
+  nsPluginType_PDF,
   nsPluginType_Other
 } nsPluginType;
 
 class nsPluginNativeWindowWin : public nsPluginNativeWindow {
 public: 
   nsPluginNativeWindowWin();
   virtual ~nsPluginNativeWindowWin();
 
@@ -158,16 +159,18 @@ public:
                                            LPARAM aLParam);
 
 private:
   WNDPROC mPrevWinProc;
   WNDPROC mPluginWinProc;
   PluginWindowWeakRef mWeakRef;
   nsRefPtr<PluginWindowEvent> mCachedPluginWindowEvent;
 
+  HWND mParentWnd;
+  LONG_PTR mParentProc;
 public:
   nsPluginType mPluginType;
 };
 
 static PRBool sInMessageDispatch = PR_FALSE;
 static UINT sLastMsg = 0;
 
 static PRBool ProcessFlashMessageDelayed(nsPluginNativeWindowWin * aWin, nsIPluginInstance * aInst,
@@ -225,33 +228,16 @@ static LRESULT CALLBACK PluginWndProc(HW
     return TRUE;
 
   // The DispatchEvent(NS_PLUGIN_ACTIVATE) below can trigger a reentrant focus
   // event which might destroy us.  Hold a strong ref on the plugin instance
   // to prevent that, bug 374229.
   nsCOMPtr<nsIPluginInstance> inst;
   win->GetPluginInstance(inst);
 
-  // check plugin mime type and cache whether it is Flash or not
-  // Flash will need special treatment later
-  if (win->mPluginType == nsPluginType_Unknown) {
-    if (inst) {
-      const char* mimetype = nsnull;
-      inst->GetMIMEType(&mimetype);
-      if (mimetype) { 
-        if (!strcmp(mimetype, "application/x-shockwave-flash"))
-          win->mPluginType = nsPluginType_Flash;
-        else if (!strcmp(mimetype, "audio/x-pn-realaudio-plugin"))
-          win->mPluginType = nsPluginType_Real;
-        else
-          win->mPluginType = nsPluginType_Other;
-      }
-    }
-  }
-
   // Real may go into a state where it recursivly dispatches the same event
   // when subclassed. If this is Real, lets examine the event and drop it
   // on the floor if we get into this recursive situation. See bug 192914.
   if (win->mPluginType == nsPluginType_Real) {
     
     if (sInMessageDispatch && (msg == sLastMsg)) {
 #ifdef DEBUG
       printf("Dropping event %d for Real on the floor\n", msg);
@@ -403,17 +389,20 @@ nsPluginNativeWindowWin::nsPluginNativeW
   x = 0; 
   y = 0; 
   width = 0; 
   height = 0; 
 
   mPrevWinProc = NULL;
   mPluginWinProc = NULL;
   mPluginType = nsPluginType_Unknown;
-  
+
+  mParentWnd = NULL;
+  mParentProc = NULL;
+
   if (sWM_FLASHBOUNCEMSG == 0)
     sWM_FLASHBOUNCEMSG = ::RegisterWindowMessage(NS_PLUGIN_CUSTOM_MSG_ID);
 
 }
 
 nsPluginNativeWindowWin::~nsPluginNativeWindowWin()
 {
   // clear weak reference to self to prevent any pending events from
@@ -498,28 +487,57 @@ nsPluginNativeWindowWin::GetPluginWindow
   return event;
 }
 
 nsresult nsPluginNativeWindowWin::CallSetWindow(nsCOMPtr<nsIPluginInstance> &aPluginInstance)
 {
   // check the incoming instance, null indicates that window is going away and we are
   // not interested in subclassing business any more, undo and don't subclass
 
+  // check plugin mime type and cache it if it will need special treatment later
+  if (mPluginType == nsPluginType_Unknown) {
+    if (aPluginInstance) {
+      const char* mimetype = nsnull;
+      aPluginInstance->GetMIMEType(&mimetype);
+      if (mimetype) { 
+        if (!strcmp(mimetype, "application/x-shockwave-flash"))
+          mPluginType = nsPluginType_Flash;
+        else if (!strcmp(mimetype, "audio/x-pn-realaudio-plugin"))
+          mPluginType = nsPluginType_Real;
+        else if (!strcmp(mimetype, "application/pdf"))
+          mPluginType = nsPluginType_PDF;
+        else
+          mPluginType = nsPluginType_Other;
+      }
+    }
+  }
+
   // WINCE does not subclass windows.  See bug 300011 for the details.
 #ifndef WINCE
   if (!aPluginInstance) {
     UndoSubclassAndAssociateWindow();
     mPrevWinProc = NULL;
   }
 
   // We need WndProc before plug-ins do subclass in nsPluginNativeWindow::CallSetWindow.
   if (aPluginInstance) {
     WNDPROC currentWndProc = (WNDPROC)::GetWindowLongPtr((HWND)window, GWLP_WNDPROC);
     if (currentWndProc != PluginWndProc)
       mPrevWinProc = currentWndProc;
+
+    // PDF plugin v7.0.9, v8.1.3, and v9.0 subclass parent window, bug 531551
+    // V8.2.2 and V9.1 don't have such problem.
+    if (mPluginType == nsPluginType_PDF) {
+      HWND parent = ::GetParent((HWND)window);
+      if (mParentWnd != parent) {
+        NS_ASSERTION(!mParentWnd, "Plugin's parent window changed");
+        mParentWnd = parent;
+        mParentProc = ::GetWindowLongPtr(mParentWnd, GWLP_WNDPROC);
+      }
+    }
   }
 #endif
 
   nsPluginNativeWindow::CallSetWindow(aPluginInstance);
 
 #ifndef WINCE
   if (aPluginInstance)
     SubclassAndAssociateWindow();
@@ -588,16 +606,22 @@ nsresult nsPluginNativeWindowWin::UndoSu
     if (currentWndProc == PluginWndProc)
       SubclassWindow(hWnd, (LONG_PTR)mPluginWinProc);
 
     LONG_PTR style = GetWindowLongPtr(hWnd, GWL_STYLE);
     style &= ~WS_CLIPCHILDREN;
     SetWindowLongPtr(hWnd, GWL_STYLE, style);
   }
 
+  if (mPluginType == nsPluginType_PDF && mParentWnd) {
+    ::SetWindowLongPtr(mParentWnd, GWLP_WNDPROC, mParentProc);
+    mParentWnd = NULL;
+    mParentProc = NULL;
+  }
+
   return NS_OK;
 }
 #endif // WINCE
 
 nsresult PLUG_NewPluginNativeWindow(nsPluginNativeWindow ** aPluginNativeWindow)
 {
   NS_ENSURE_ARG_POINTER(aPluginNativeWindow);