Bug 1338172 part C - Remove support for windowed mode plugins on Linux (GTK). r?jimm draft
authorBenjamin Smedberg <benjamin@smedbergs.us>
Thu, 09 Feb 2017 10:05:00 -0500
changeset 481917 bbbba335928e1a6cb0663cf7be1c8ae96d832069
parent 481916 f38b1c5090bead5a490636448320d85443b48d9a
child 481918 5addbd30c9ab7aaf40b117d0d59e6069818b9f67
push id44958
push userbsmedberg@mozilla.com
push dateFri, 10 Feb 2017 19:35:35 +0000
reviewersjimm
bugs1338172
milestone54.0a1
Bug 1338172 part C - Remove support for windowed mode plugins on Linux (GTK). r?jimm MozReview-Commit-ID: 5rnxozEKCwn
dom/plugins/ipc/PPluginInstance.ipdl
dom/plugins/ipc/PluginInstanceChild.cpp
dom/plugins/ipc/PluginInstanceChild.h
dom/plugins/ipc/PluginInstanceParent.cpp
dom/plugins/ipc/PluginModuleChild.cpp
--- a/dom/plugins/ipc/PPluginInstance.ipdl
+++ b/dom/plugins/ipc/PPluginInstance.ipdl
@@ -82,20 +82,16 @@ child:
   // This is only used on Windows and, for windowless plugins.
   async CreateChildPopupSurrogate(NativeWindowHandle netscapeWindow);
 
   intr NPP_SetWindow(NPRemoteWindow window);
 
   intr NPP_GetValue_NPPVpluginWantsAllNetworkStreams()
     returns (bool value, NPError result);
 
-  // this message is not used on non-X platforms
-  intr NPP_GetValue_NPPVpluginNeedsXEmbed()
-    returns (bool value, NPError result);
-
   intr NPP_GetValue_NPPVpluginScriptableNPObject()
     returns (nullable PPluginScriptableObject value, NPError result);
 
   intr NPP_SetValue_NPNVprivateModeBool(bool value) returns (NPError result);
   intr NPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId()
     returns (nsCString plug_id, NPError result);
 
   intr NPP_SetValue_NPNVCSSZoomFactor(double value) returns (NPError result);
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -147,19 +147,16 @@ PluginInstanceChild::PluginInstanceChild
     , mPostingKeyEvents(0)
     , mPostingKeyEventsOutdated(0)
     , mDrawingModel(kDefaultDrawingModel)
     , mCurrentDirectSurface(nullptr)
     , mAsyncInvalidateMutex("PluginInstanceChild::mAsyncInvalidateMutex")
     , mAsyncInvalidateTask(0)
     , mCachedWindowActor(nullptr)
     , mCachedElementActor(nullptr)
-#ifdef MOZ_WIDGET_GTK
-    , mXEmbed(false)
-#endif // MOZ_WIDGET_GTK
 #if defined(OS_WIN)
     , mPluginWindowHWND(0)
     , mPluginWndProc(0)
     , mPluginParentHWND(0)
     , mCachedWinlessPluginHWND(0)
     , mWinlessPopupSurrogateHWND(0)
     , mWinlessThrottleOldWndProc(0)
     , mWinlessHiddenMsgHWND(0)
@@ -196,17 +193,16 @@ PluginInstanceChild::PluginInstanceChild
     mWindow.type = NPWindowTypeWindow;
     mData.ndata = (void*) this;
     mData.pdata = nullptr;
 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
     mWindow.ws_info = &mWsInfo;
     memset(&mWsInfo, 0, sizeof(mWsInfo));
 #ifdef MOZ_WIDGET_GTK
     mWsInfo.display = nullptr;
-    mXtClient.top_widget = nullptr;
 #else
     mWsInfo.display = DefaultXDisplay();
 #endif
 #endif // MOZ_X11 && XP_UNIX && !XP_MACOSX
 #if defined(OS_WIN)
     InitPopupMenuHook();
     InitImm32Hook();
 #endif // OS_WIN
@@ -576,34 +572,24 @@ PluginInstanceChild::NPN_SetValue(NPPVar
 
     AutoStackHelper guard(this);
 
     switch (aVar) {
     case NPPVpluginWindowBool: {
         NPError rv;
         bool windowed = (NPBool) (intptr_t) aValue;
 
+        if (windowed) {
+            return NPERR_GENERIC_ERROR;
+        }
+
         if (!CallNPN_SetValue_NPPVpluginWindow(windowed, &rv))
             return NPERR_GENERIC_ERROR;
 
-        NPWindowType newWindowType = windowed ? NPWindowTypeWindow : NPWindowTypeDrawable;
-#ifdef MOZ_WIDGET_GTK
-        if (mWindow.type != newWindowType && mWsInfo.display) {
-           // plugin type has been changed but we already have a valid display
-           // so update it for the recent plugin mode
-           if (mXEmbed || !windowed) {
-               // Use default GTK display for XEmbed and windowless plugins
-               mWsInfo.display = DefaultXDisplay();
-           }
-           else {
-               mWsInfo.display = xt_client_get_display();
-           }
-        }
-#endif
-        mWindow.type = newWindowType;
+        mWindow.type = NPWindowTypeDrawable;
         return rv;
     }
 
     case NPPVpluginTransparentBool: {
         NPError rv;
         mIsTransparent = (!!aValue);
 
         if (!CallNPN_SetValue_NPPVpluginTransparent(mIsTransparent, &rv))
@@ -707,50 +693,16 @@ PluginInstanceChild::AnswerNPP_GetValue_
         *rv = mPluginIface->getvalue(GetNPP(), NPPVpluginWantsAllNetworkStreams,
                                      &value);
     }
     *wantsAllStreams = value;
     return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginNeedsXEmbed(
-    bool* needs, NPError* rv)
-{
-    AssertPluginThread();
-    AutoStackHelper guard(this);
-
-#ifdef MOZ_X11
-    // The documentation on the types for many variables in NP(N|P)_GetValue
-    // is vague.  Often boolean values are NPBool (1 byte), but
-    // https://developer.mozilla.org/en/XEmbed_Extension_for_Mozilla_Plugins
-    // treats NPPVpluginNeedsXEmbed as PRBool (int), and
-    // on x86/32-bit, flash stores to this using |movl 0x1,&needsXEmbed|.
-    // thus we can't use NPBool for needsXEmbed, or the three bytes above
-    // it on the stack would get clobbered. so protect with the larger bool.
-    int needsXEmbed = 0;
-    if (!mPluginIface->getvalue) {
-        *rv = NPERR_GENERIC_ERROR;
-    }
-    else {
-        *rv = mPluginIface->getvalue(GetNPP(), NPPVpluginNeedsXEmbed,
-                                     &needsXEmbed);
-    }
-    *needs = needsXEmbed;
-    return IPC_OK();
-
-#else
-
-    NS_RUNTIMEABORT("shouldn't be called on non-X11 platforms");
-    return IPC_FAIL_NO_REASON(this);               // not reached
-
-#endif
-}
-
-mozilla::ipc::IPCResult
 PluginInstanceChild::AnswerNPP_GetValue_NPPVpluginScriptableNPObject(
                                           PPluginScriptableObjectChild** aValue,
                                           NPError* aResult)
 {
     AssertPluginThread();
     AutoStackHelper guard(this);
 
     NPObject* object = nullptr;
@@ -1162,68 +1114,16 @@ PluginInstanceChild::RecvContentsScaleFa
 #endif
     return IPC_OK();
 #else
     NS_RUNTIMEABORT("ContentsScaleFactorChanged is an Windows or OSX only message");
     return IPC_FAIL_NO_REASON(this);
 #endif
 }
 
-#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
-// Create a new window from NPWindow
-bool PluginInstanceChild::CreateWindow(const NPRemoteWindow& aWindow)
-{ 
-    PLUGIN_LOG_DEBUG(("%s (aWindow=<window: 0x%lx, x: %d, y: %d, width: %d, height: %d>)",
-                      FULLFUNCTION,
-                      aWindow.window,
-                      aWindow.x, aWindow.y,
-                      aWindow.width, aWindow.height));
-
-#ifdef MOZ_WIDGET_GTK
-    if (mXEmbed) {
-        mWindow.window = reinterpret_cast<void*>(aWindow.window);
-    }
-    else {
-        Window browserSocket = (Window)(aWindow.window);
-        xt_client_init(&mXtClient, mWsInfo.visual, mWsInfo.colormap, mWsInfo.depth);
-        xt_client_create(&mXtClient, browserSocket, mWindow.width, mWindow.height); 
-        mWindow.window = (void *)XtWindow(mXtClient.child_widget);
-    }  
-#else
-    mWindow.window = reinterpret_cast<void*>(aWindow.window);
-#endif
-
-    return true;
-}
-
-// Destroy window
-void PluginInstanceChild::DeleteWindow()
-{
-  PLUGIN_LOG_DEBUG(("%s (aWindow=<window: 0x%lx, x: %d, y: %d, width: %d, height: %d>)",
-                    FULLFUNCTION,
-                    mWindow.window,
-                    mWindow.x, mWindow.y,
-                    mWindow.width, mWindow.height));
-
-  if (!mWindow.window)
-      return;
-
-#ifdef MOZ_WIDGET_GTK
-  if (mXtClient.top_widget) {     
-      xt_client_unrealize(&mXtClient);
-      xt_client_destroy(&mXtClient); 
-      mXtClient.top_widget = nullptr;
-  }
-#endif
-
-  // We don't have to keep the plug-in window ID any longer.
-  mWindow.window = nullptr;
-}
-#endif
-
 mozilla::ipc::IPCResult
 PluginInstanceChild::AnswerCreateChildPluginWindow(NativeWindowHandle* aChildPluginWindow)
 {
 #if defined(XP_WIN)
     MOZ_ASSERT(!mPluginWindowHWND);
 
     if (!CreatePluginWindow()) {
         return IPC_FAIL_NO_REASON(this);
@@ -1279,55 +1179,16 @@ PluginInstanceChild::AnswerNPP_SetWindow
     mWindow.type = aWindow.type;
 
     mWsInfo.colormap = aWindow.colormap;
     int depth;
     FindVisualAndDepth(mWsInfo.display, aWindow.visualID,
                        &mWsInfo.visual, &depth);
     mWsInfo.depth = depth;
 
-    if (!mWindow.window && mWindow.type == NPWindowTypeWindow) {
-        CreateWindow(aWindow);
-    }
-
-#ifdef MOZ_WIDGET_GTK
-    if (mXEmbed && gtk_check_version(2,18,7) != nullptr) { // older
-        if (aWindow.type == NPWindowTypeWindow) {
-            GdkWindow* socket_window = gdk_window_lookup(static_cast<GdkNativeWindow>(aWindow.window));
-            if (socket_window) {
-                // A GdkWindow for the socket already exists.  Need to
-                // workaround https://bugzilla.gnome.org/show_bug.cgi?id=607061
-                // See wrap_gtk_plug_embedded in PluginModuleChild.cpp.
-                g_object_set_data(G_OBJECT(socket_window),
-                                  "moz-existed-before-set-window",
-                                  GUINT_TO_POINTER(1));
-            }
-        }
-
-        if (aWindow.visualID != X11None
-            && gtk_check_version(2, 12, 10) != nullptr) { // older
-            // Workaround for a bug in Gtk+ (prior to 2.12.10) where deleting
-            // a foreign GdkColormap will also free the XColormap.
-            // http://git.gnome.org/browse/gtk+/log/gdk/x11/gdkcolor-x11.c?id=GTK_2_12_10
-            GdkVisual *gdkvisual = gdkx_visual_get(aWindow.visualID);
-            GdkColormap *gdkcolor =
-                gdk_x11_colormap_foreign_new(gdkvisual, aWindow.colormap);
-
-            if (g_object_get_data(G_OBJECT(gdkcolor), "moz-have-extra-ref")) {
-                // We already have a ref to keep the object alive.
-                g_object_unref(gdkcolor);
-            } else {
-                // leak and mark as already leaked
-                g_object_set_data(G_OBJECT(gdkcolor),
-                                  "moz-have-extra-ref", GUINT_TO_POINTER(1));
-            }
-        }
-    }
-#endif
-
     PLUGIN_LOG_DEBUG(
         ("[InstanceChild][%p] Answer_SetWindow w=<x=%d,y=%d, w=%d,h=%d>, clip=<l=%d,t=%d,r=%d,b=%d>",
          this, mWindow.x, mWindow.y, mWindow.width, mWindow.height,
          mWindow.clipRect.left, mWindow.clipRect.top, mWindow.clipRect.right, mWindow.clipRect.bottom));
 
     if (mPluginIface->setwindow)
         (void) mPluginIface->setwindow(&mData, &mWindow);
 
@@ -1407,40 +1268,27 @@ PluginInstanceChild::AnswerNPP_SetWindow
 
     return IPC_OK();
 }
 
 bool
 PluginInstanceChild::Initialize()
 {
 #ifdef MOZ_WIDGET_GTK
-    NPError rv;
-
     if (mWsInfo.display) {
         // Already initialized
         return true;
     }
 
     // Request for windowless plugins is set in newp(), before this call.
     if (mWindow.type == NPWindowTypeWindow) {
-        AnswerNPP_GetValue_NPPVpluginNeedsXEmbed(&mXEmbed, &rv);
-
-        // Set up Xt loop for windowed plugins without XEmbed support
-        if (!mXEmbed) {
-           xt_client_xloop_create();
-        }
+        return false;
     }
 
-    // Use default GTK display for XEmbed and windowless plugins
-    if (mXEmbed || mWindow.type != NPWindowTypeWindow) {
-        mWsInfo.display = DefaultXDisplay();
-    }
-    else {
-        mWsInfo.display = xt_client_get_display();
-    }
+    mWsInfo.display = DefaultXDisplay();
 #endif
 
 #if defined(XP_MACOSX) && defined(__i386__)
     // If an i386 Mac OS X plugin has selected the Carbon event model then
     // we have to fail. We do not support putting Carbon event model plugins
     // out of process. Note that Carbon is the default model so out of process
     // plugins need to actively negotiate something else in order to work
     // out of process.
@@ -4499,25 +4347,16 @@ PluginInstanceChild::Destroy()
 #endif
 
     // Pending async calls are discarded, not delivered. This matches the
     // in-process behavior.
     for (uint32_t i = 0; i < mPendingAsyncCalls.Length(); ++i)
         mPendingAsyncCalls[i]->Cancel();
 
     mPendingAsyncCalls.Clear();
-    
-#ifdef MOZ_WIDGET_GTK
-    if (mWindow.type == NPWindowTypeWindow && !mXEmbed) {
-      xt_client_xloop_destroy();
-    }
-#endif
-#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
-    DeleteWindow();
-#endif
 }
 
 mozilla::ipc::IPCResult
 PluginInstanceChild::AnswerNPP_Destroy(NPError* aResult)
 {
     PLUGIN_LOG_DEBUG_METHOD;
     AssertPluginThread();
     *aResult = NPERR_NO_ERROR;
--- a/dom/plugins/ipc/PluginInstanceChild.h
+++ b/dom/plugins/ipc/PluginInstanceChild.h
@@ -74,18 +74,16 @@ protected:
     RecvCreateChildPopupSurrogate(const NativeWindowHandle& aNetscapeWindow) override;
 
     virtual mozilla::ipc::IPCResult
     AnswerNPP_SetWindow(const NPRemoteWindow& window) override;
 
     virtual mozilla::ipc::IPCResult
     AnswerNPP_GetValue_NPPVpluginWantsAllNetworkStreams(bool* wantsAllStreams, NPError* rv) override;
     virtual mozilla::ipc::IPCResult
-    AnswerNPP_GetValue_NPPVpluginNeedsXEmbed(bool* needs, NPError* rv) override;
-    virtual mozilla::ipc::IPCResult
     AnswerNPP_GetValue_NPPVpluginScriptableNPObject(PPluginScriptableObjectChild** value,
                                                     NPError* result) override;
     virtual mozilla::ipc::IPCResult
     AnswerNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(nsCString* aPlugId,
                                                            NPError* aResult) override;
     virtual mozilla::ipc::IPCResult
     AnswerNPP_SetValue_NPNVprivateModeBool(const bool& value, NPError* result) override;
     virtual mozilla::ipc::IPCResult
@@ -204,21 +202,16 @@ protected:
     AnswerSetPluginFocus() override;
 
     virtual mozilla::ipc::IPCResult
     AnswerUpdateWindow() override;
 
     virtual mozilla::ipc::IPCResult
     RecvNPP_DidComposite() override;
 
-#if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
-    bool CreateWindow(const NPRemoteWindow& aWindow);
-    void DeleteWindow();
-#endif
-
 public:
     PluginInstanceChild(const NPPluginFuncs* aPluginIface,
                         const nsCString& aMimeType,
                         const uint16_t& aMode,
                         const InfallibleTArray<nsCString>& aNames,
                         const InfallibleTArray<nsCString>& aValues);
 
     virtual ~PluginInstanceChild();
@@ -452,17 +445,16 @@ private:
 
     // Cached scriptable actors to avoid IPC churn
     PluginScriptableObjectChild* mCachedWindowActor;
     PluginScriptableObjectChild* mCachedElementActor;
 
 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
     NPSetWindowCallbackStruct mWsInfo;
 #ifdef MOZ_WIDGET_GTK
-    bool mXEmbed;
     XtClient mXtClient;
 #endif
 #elif defined(OS_WIN)
     HWND mPluginWindowHWND;
     WNDPROC mPluginWndProc;
     HWND mPluginParentHWND;
     int mNestedEventLevelDepth;
     HWND mCachedWinlessPluginHWND;
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -1435,34 +1435,16 @@ PluginInstanceParent::NPP_GetValue(NPPVa
         if (NPERR_NO_ERROR != rv) {
             return rv;
         }
 
         (*(NPBool*)_retval) = wantsAllStreams;
         return NPERR_NO_ERROR;
     }
 
-#ifdef MOZ_X11
-    case NPPVpluginNeedsXEmbed: {
-        bool needsXEmbed;
-        NPError rv;
-
-        if (!CallNPP_GetValue_NPPVpluginNeedsXEmbed(&needsXEmbed, &rv)) {
-            return NPERR_GENERIC_ERROR;
-        }
-
-        if (NPERR_NO_ERROR != rv) {
-            return rv;
-        }
-
-        (*(NPBool*)_retval) = needsXEmbed;
-        return NPERR_NO_ERROR;
-    }
-#endif
-
     case NPPVpluginScriptableNPObject: {
         PPluginScriptableObjectParent* actor;
         NPError rv;
         if (!CallNPP_GetValue_NPPVpluginScriptableNPObject(&actor, &rv)) {
             return NPERR_GENERIC_ERROR;
         }
 
         if (NPERR_NO_ERROR != rv) {
--- a/dom/plugins/ipc/PluginModuleChild.cpp
+++ b/dom/plugins/ipc/PluginModuleChild.cpp
@@ -1100,30 +1100,30 @@ NPError
             return NPERR_NO_ERROR;
         case NPNVasdEnabledBool:
             *(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().asdEnabled();
             return NPERR_NO_ERROR;
         case NPNVisOfflineBool:
             *(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().isOffline();
             return NPERR_NO_ERROR;
         case NPNVSupportsXEmbedBool:
-            *(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().supportsXembed();
+            // We don't support windowed xembed any more. But we still deliver
+            // events based on X/GTK, not Xt, so we continue to return true
+            // (and Flash requires that we return true).
+            *(NPBool*)aValue = true;
             return NPERR_NO_ERROR;
         case NPNVSupportsWindowless:
-            *(NPBool*)aValue = PluginModuleChild::GetChrome()->Settings().supportsWindowless();
+            *(NPBool*)aValue = true;
             return NPERR_NO_ERROR;
 #if defined(MOZ_WIDGET_GTK)
         case NPNVxDisplay: {
-            if (aNPP) {
-                return InstCast(aNPP)->NPN_GetValue(aVariable, aValue);
-            } 
-            else {
-                *(void **)aValue = xt_client_get_display();
-            }          
-            return NPERR_NO_ERROR;
+            if (!aNPP) {
+                return NPERR_INVALID_INSTANCE_ERROR;
+            }
+            return InstCast(aNPP)->NPN_GetValue(aVariable, aValue);
         }
         case NPNVxtAppContext:
             return NPERR_GENERIC_ERROR;
 #endif
         default: {
             if (aNPP) {
                 return InstCast(aNPP)->NPN_GetValue(aVariable, aValue);
             }