Bug 669200 - Add support for gtk socket widgets for plugin windows. r=roc
authorJim Mathies <jmathies@mozilla.com>
Wed, 12 Nov 2014 14:59:21 -0600
changeset 215365 99bad02916c630f5ddaed2f11308952b0f5d69ba
parent 215364 706254cbf092abf11de082fdfdd001f1529d43bd
child 215366 f72f08089393277f57d316645340325946ab3e85
push id27813
push userkwierso@gmail.com
push dateThu, 13 Nov 2014 01:03:17 +0000
treeherdermozilla-central@64f1fb1e2f38 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs669200
milestone36.0a1
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 669200 - Add support for gtk socket widgets for plugin windows. r=roc
dom/plugins/base/moz.build
dom/plugins/base/nsPluginNativeWindowGtk.cpp
dom/plugins/base/nsPluginNativeWindowGtk.h
dom/plugins/ipc/PluginWidgetParent.cpp
dom/plugins/ipc/PluginWidgetParent.h
widget/PluginWidgetProxy.cpp
--- a/dom/plugins/base/moz.build
+++ b/dom/plugins/base/moz.build
@@ -26,16 +26,17 @@ EXPORTS += [
     'nptypes.h',
     'nsJSNPRuntime.h',
     'nsNPAPIPluginInstance.h',
     'nsPluginDirServiceProvider.h',
     'nsPluginHost.h',
     'nsPluginInstanceOwner.h',
     'nsPluginLogging.h',
     'nsPluginNativeWindow.h',
+    'nsPluginNativeWindowGtk.h',
     'nsPluginPlayPreviewInfo.h',
     'nsPluginsCID.h',
     'nsPluginsDir.h',
     'nsPluginTags.h',
 ]
 
 EXPORTS.mozilla += [
     'PluginPRLibrary.h',
--- a/dom/plugins/base/nsPluginNativeWindowGtk.cpp
+++ b/dom/plugins/base/nsPluginNativeWindowGtk.cpp
@@ -5,59 +5,30 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /**
  *  This file is the Gtk2 implementation of plugin native window.
  */
 
 #include "nsDebug.h"
-#include "nsPluginNativeWindow.h"
+#include "nsPluginNativeWindowGtk.h"
 #include "nsNPAPIPlugin.h"
 #include "npapi.h"
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
 #include <gdk/gdk.h>
 
 #if (GTK_MAJOR_VERSION == 3)
 #include <gtk/gtkx.h>
 #else
 #include "gtk2xtbin.h"
 #endif
 #include "mozilla/X11Util.h"
 
-class nsPluginNativeWindowGtk : public nsPluginNativeWindow {
-public: 
-  nsPluginNativeWindowGtk();
-  virtual ~nsPluginNativeWindowGtk();
-
-  virtual nsresult CallSetWindow(nsRefPtr<nsNPAPIPluginInstance> &aPluginInstance);
-private:
-  void SetWindow(XID aWindow)
-  {
-    window = reinterpret_cast<void*>(static_cast<uintptr_t>(aWindow));
-  }
-  XID GetWindow() const
-  {
-    return static_cast<XID>(reinterpret_cast<uintptr_t>(window));
-  }
-
-  NPSetWindowCallbackStruct mWsInfo;
-  /**
-   * Either a GtkSocket or a special GtkXtBin widget (derived from GtkSocket)
-   * that encapsulates the Xt toolkit within a Gtk Application.
-   */
-  GtkWidget* mSocketWidget;
-  nsresult  CreateXEmbedWindow(bool aEnableXtFocus);
-#if (MOZ_WIDGET_GTK == 2)
-  nsresult  CreateXtWindow();
-#endif
-  void      SetAllocation();
-};
-
 static gboolean plug_removed_cb   (GtkWidget *widget, gpointer data);
 static void socket_unrealize_cb   (GtkWidget *widget, gpointer data);
 
 nsPluginNativeWindowGtk::nsPluginNativeWindowGtk() : nsPluginNativeWindow()
 {
   // initialize the struct fields
   window = nullptr; 
   x = 0; 
new file mode 100644
--- /dev/null
+++ b/dom/plugins/base/nsPluginNativeWindowGtk.h
@@ -0,0 +1,52 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _nsPluginNativeWindowGdk_h_
+#define _nsPluginNativeWindowGdk_h_
+
+#include "nsPluginNativeWindow.h"
+#include "nsNPAPIPlugin.h"
+#include "npapi.h"
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdk.h>
+#if (GTK_MAJOR_VERSION == 3)
+#include <gtk/gtkx.h>
+#else
+#include "gtk2xtbin.h"
+#endif
+#include "mozilla/X11Util.h"
+
+class nsPluginNativeWindowGtk : public nsPluginNativeWindow {
+public:
+  nsPluginNativeWindowGtk();
+  virtual ~nsPluginNativeWindowGtk();
+
+  virtual nsresult CallSetWindow(nsRefPtr<nsNPAPIPluginInstance> &aPluginInstance);
+  nsresult CreateXEmbedWindow(bool aEnableXtFocus);
+  void SetAllocation();
+
+  XID GetWindow() const
+  {
+    return static_cast<XID>(reinterpret_cast<uintptr_t>(window));
+  }
+
+private:
+  void SetWindow(XID aWindow)
+  {
+    window = reinterpret_cast<void*>(static_cast<uintptr_t>(aWindow));
+  }
+
+  NPSetWindowCallbackStruct mWsInfo;
+  /**
+   * Either a GtkSocket or a special GtkXtBin widget (derived from GtkSocket)
+   * that encapsulates the Xt toolkit within a Gtk Application.
+   */
+  GtkWidget* mSocketWidget;
+#if (MOZ_WIDGET_GTK == 2)
+  nsresult  CreateXtWindow();
+#endif
+};
+
+#endif
--- a/dom/plugins/ipc/PluginWidgetParent.cpp
+++ b/dom/plugins/ipc/PluginWidgetParent.cpp
@@ -3,16 +3,22 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "PluginWidgetParent.h"
 #include "mozilla/dom/TabParent.h"
 #include "nsComponentManagerUtils.h"
 #include "nsWidgetsCID.h"
 #include "nsDebug.h"
 
+#if defined(MOZ_WIDGET_GTK)
+#include "nsPluginNativeWindowGtk.h"
+#else
+#include "nsPluginNativeWindow.h"
+#endif
+
 using namespace mozilla::widget;
 
 #define PWLOG(...)
 // #define PWLOG(...) printf_stderr(__VA_ARGS__)
 
 namespace mozilla {
 namespace plugins {
 
@@ -23,16 +29,19 @@ static NS_DEFINE_CID(kWidgetCID, NS_CHIL
 #define ENSURE_CHANNEL {                                      \
   if (!mWidget) {                                             \
     NS_WARNING("called on an invalid remote widget.");        \
     return true;                                              \
   }                                                           \
 }
 
 PluginWidgetParent::PluginWidgetParent()
+#if defined(MOZ_WIDGET_GTK)
+  : mWrapper(nullptr)
+#endif
 {
   PWLOG("PluginWidgetParent::PluginWidgetParent()\n");
   MOZ_COUNT_CTOR(PluginWidgetParent);
 }
 
 PluginWidgetParent::~PluginWidgetParent()
 {
   PWLOG("PluginWidgetParent::~PluginWidgetParent()\n");
@@ -55,29 +64,37 @@ PluginWidgetParent::GetTabParent()
 void
 PluginWidgetParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   PWLOG("PluginWidgetParent::ActorDestroy()\n");
 }
 
 // When plugins run in chrome, nsPluginNativeWindow(Plat) implements platform
 // specific functionality that wraps plugin widgets. With e10s we currently
-// bypass this code since we can't connect up platform specific bits in the
-// content process. We may need to instantiate nsPluginNativeWindow here and
-// enable some of its logic.
+// bypass this code on Window, and reuse a bit of it on Linux. Content still
+// makes use of some of the utility functions as well.
 
 bool
 PluginWidgetParent::RecvCreate()
 {
   PWLOG("PluginWidgetParent::RecvCreate()\n");
 
   nsresult rv;
 
   mWidget = do_CreateInstance(kWidgetCID, &rv);
 
+#if defined(MOZ_WIDGET_GTK)
+  // We need this currently just for GTK in setting up a socket widget
+  // we can send over to content -> plugin.
+  PLUG_NewPluginNativeWindow((nsPluginNativeWindow**)&mWrapper);
+  if (!mWrapper) {
+    return false;
+  }
+#endif
+
   // This returns the top level window widget
   nsCOMPtr<nsIWidget> parentWidget = GetTabParent()->GetWidget();
 
   nsWidgetInitData initData;
   initData.mWindowType = eWindowType_plugin_ipc_chrome;
   initData.mUnicode = false;
   initData.clipChildren = true;
   initData.clipSiblings = true;
@@ -93,16 +110,24 @@ PluginWidgetParent::RecvCreate()
   mWidget->Show(false);
   mWidget->Enable(false);
 
   // Force the initial position down into content. If we miss an
   // initial position update this insures the widget doesn't overlap
   // chrome.
   RecvMove(0, 0);
 
+#if defined(MOZ_WIDGET_GTK)
+  // For setup, initially GTK code expects 'window' to hold the parent.
+  mWrapper->window = mWidget->GetNativeData(NS_NATIVE_PLUGIN_PORT);
+  mWrapper->CreateXEmbedWindow(false);
+  mWrapper->SetAllocation();
+  PWLOG("Plugin XID=%p\n", (void*)mWrapper->window);
+#endif
+
   return true;
 }
 
 bool
 PluginWidgetParent::RecvDestroy()
 {
   ENSURE_CHANNEL;
   PWLOG("PluginWidgetParent::RecvDestroy()\n");
@@ -138,26 +163,36 @@ PluginWidgetParent::RecvInvalidate(const
   return true;
 }
 
 bool
 PluginWidgetParent::RecvGetNativePluginPort(uintptr_t* value)
 {
   ENSURE_CHANNEL;
   PWLOG("PluginWidgetParent::RecvGetNativeData()\n");
+#if defined(MOZ_WIDGET_GTK)
+  *value = (uintptr_t)mWrapper->window;
+#else
   *value = (uintptr_t)mWidget->GetNativeData(NS_NATIVE_PLUGIN_PORT);
+#endif
+  PWLOG("PluginWidgetParent::RecvGetNativeData() %p\n", (void*)*value);
   return true;
 }
 
 bool
 PluginWidgetParent::RecvResize(const nsIntRect& aRect)
 {
   ENSURE_CHANNEL;
   PWLOG("PluginWidgetParent::RecvResize(%d, %d, %d, %d)\n", aRect.x, aRect.y, aRect.width, aRect.height);
   mWidget->Resize(aRect.width, aRect.height, true);
+#if defined(MOZ_WIDGET_GTK)
+  mWrapper->width = aRect.width;
+  mWrapper->height = aRect.height;
+  mWrapper->SetAllocation();
+#endif
   return true;
 }
 
 bool
 PluginWidgetParent::RecvMove(const double& aX, const double& aY)
 {
   ENSURE_CHANNEL;
   PWLOG("PluginWidgetParent::RecvMove(%f, %f)\n", aX, aY);
--- a/dom/plugins/ipc/PluginWidgetParent.h
+++ b/dom/plugins/ipc/PluginWidgetParent.h
@@ -4,16 +4,20 @@
 
 #ifndef mozilla_plugins_PluginWidgetParent_h
 #define mozilla_plugins_PluginWidgetParent_h
 
 #include "mozilla/plugins/PPluginWidgetParent.h"
 #include "nsIWidget.h"
 #include "nsCOMPtr.h"
 
+#if defined(MOZ_WIDGET_GTK)
+class nsPluginNativeWindowGtk;
+#endif
+
 namespace mozilla {
 
 namespace dom {
 class TabParent;
 }
 
 namespace plugins {
 
@@ -35,15 +39,18 @@ public:
   virtual bool RecvSetWindowClipRegion(const nsTArray<nsIntRect>& Regions,
                                         const bool& aIntersectWithExisting) MOZ_OVERRIDE;
 
 private:
   // The tab our connection is associated with.
   mozilla::dom::TabParent* GetTabParent();
   // The chrome side native widget.
   nsCOMPtr<nsIWidget> mWidget;
+#if defined(MOZ_WIDGET_GTK)
+  UniquePtr<nsPluginNativeWindowGtk> mWrapper;
+#endif
 };
 
 } // namespace plugins
 } // namespace mozilla
 
 #endif // mozilla_plugins_PluginWidgetParent_h
 
--- a/widget/PluginWidgetProxy.cpp
+++ b/widget/PluginWidgetProxy.cpp
@@ -138,16 +138,17 @@ PluginWidgetProxy::GetNativeData(uint32_
     case NS_NATIVE_SHAREABLE_WINDOW:
       break;
     default:
       NS_WARNING("PluginWidgetProxy::GetNativeData received request for unsupported data type.");
       return nullptr;
   }
   uintptr_t value = 0;
   mActor->SendGetNativePluginPort(&value);
+  PWLOG("PluginWidgetProxy::GetNativeData %p\n", (void*)value);
   return (void*)value;
 }
 
 NS_IMETHODIMP
 PluginWidgetProxy::Resize(double aWidth, double aHeight, bool aRepaint)
 {
   ENSURE_CHANNEL;
   PWLOG("PluginWidgetProxy::Resize(%0.2f, %0.2f, %d)\n", aWidth, aHeight, aRepaint);