fix more bustage related to nsresult-to-bool switch. committing initial (untested!) NPEvent forwarding caught in the crossfire
authorChris Jones <jones.chris.g@gmail.com>
Fri, 18 Sep 2009 20:19:11 -0500
changeset 35933 c74aee79ad4d6a94f005914bf10e317160a8a2f6
parent 35932 7070ef333a405740e4b10500eb01034f548156ec
child 35934 4ed2794d25e1c0aa65ef14b750b999365ec502c5
push id10694
push userbsmedberg@mozilla.com
push dateMon, 14 Dec 2009 15:23:10 +0000
treeherderautoland@683dfdc4adf0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.3a1pre
fix more bustage related to nsresult-to-bool switch. committing initial (untested!) NPEvent forwarding caught in the crossfire
dom/plugins/Makefile.in
dom/plugins/NPEventOSX.h
dom/plugins/NPEventWindows.h
dom/plugins/NPEventX11.h
dom/plugins/PPluginInstance.ipdl
dom/plugins/PluginInstanceChild.cpp
dom/plugins/PluginInstanceChild.h
dom/plugins/PluginInstanceParent.cpp
dom/plugins/PluginInstanceParent.h
dom/plugins/PluginMessageUtils.h
dom/plugins/PluginModuleParent.cpp
--- a/dom/plugins/Makefile.in
+++ b/dom/plugins/Makefile.in
@@ -53,29 +53,32 @@ EXPORTS_mozilla = \
   SharedPRLibrary.h \
   $(NULL)
 
 ifdef MOZ_IPC
 
 EXPORTS_NAMESPACES = mozilla mozilla/plugins
 
 EXPORTS_mozilla/plugins = \
-  PluginModuleChild.h \
-  PluginModuleParent.h \
-  PluginScriptableObjectChild.h \
-  PluginScriptableObjectParent.h \
+  BrowserStreamChild.h \
+  BrowserStreamParent.h \
+  NPEventOSX.h \
+  NPEventWindows.h \
+  NPEventX11.h \
   PluginInstanceChild.h \
   PluginInstanceParent.h \
-  BrowserStreamChild.h \
-  BrowserStreamParent.h \
   PluginMessageUtils.h \
+  PluginModuleChild.h \
+  PluginModuleParent.h \
   PluginProcessParent.h \
+  PluginScriptableObjectChild.h \
+  PluginScriptableObjectParent.h \
   PluginThreadChild.h \
+  StreamNotifyChild.h \
   StreamNotifyParent.h \
-  StreamNotifyChild.h \
   $(NULL)
 
 MODULE           = dom
 LIBRARY_NAME     = domplugins_s
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
 EXPORT_LIBRARY = 1
 ENABLE_CXX_EXCEPTIONS = 1
new file mode 100644
--- /dev/null
+++ b/dom/plugins/NPEventOSX.h
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8 -*- */
+/* vim: set sw=4 ts=8 et tw=80 ft=cpp : */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_dom_plugins_NPEventOSX_h
+#define mozilla_dom_plugins_NPEventOSX_h 1
+
+
+#include "npapi.h"
+
+#warning This is only a stub implementation IMPLEMENT ME
+
+template <>
+struct ParamTraits<NPEvent>
+{
+    typedef NPEvent paramType;
+
+    static void Write(Message* aMsg, const paramType& aParam)
+    {
+    }
+
+    static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+    {
+        return true;
+    }
+
+    static void Log(const paramType& aParam, std::wstring* aLog)
+    {
+    }
+};
+
+
+#endif // ifndef mozilla_dom_plugins_NPEventOSX_h
new file mode 100644
--- /dev/null
+++ b/dom/plugins/NPEventWindows.h
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8 -*- */
+/* vim: set sw=4 ts=8 et tw=80 ft=cpp : */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_dom_plugins_NPEventWindows_h
+#define mozilla_dom_plugins_NPEventWindows_h 1
+
+
+#include "npapi.h"
+
+#warning This is only a stub implementation IMPLEMENT ME
+
+template <>
+struct ParamTraits<NPEvent>
+{
+    typedef NPEvent paramType;
+
+    static void Write(Message* aMsg, const paramType& aParam)
+    {
+    }
+
+    static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+    {
+        return true;
+    }
+
+    static void Log(const paramType& aParam, std::wstring* aLog)
+    {
+    }
+};
+
+
+#endif // ifndef mozilla_dom_plugins_NPEventWindows_h
new file mode 100644
--- /dev/null
+++ b/dom/plugins/NPEventX11.h
@@ -0,0 +1,134 @@
+/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8 -*- */
+/* vim: set sw=4 ts=8 et tw=80 ft=cpp : */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Plugin App.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Chris Jones <jones.chris.g@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_dom_plugins_NPEventX11_h
+#define mozilla_dom_plugins_NPEventX11_h 1
+
+#if defined(MOZ_WIDGET_GTK2)
+#  include <gdk/gdkx.h>
+#else
+#  error Implement me for your toolkit
+#endif
+
+#include "npapi.h"
+
+//
+// XEvent is defined as a union of all more specific X*Events.
+// Luckily, as of xorg 1.6.0 / X protocol 11 rev 0, the only pointer
+// field contained in any of these specific X*Event structs is a
+// |Display*|.  So to simplify serializing these XEvents, we make the
+// 
+// ********** XXX ASSUMPTION XXX **********
+//
+// that the process to which the event is forwarded shares the same
+// display as the process on which the event originated.
+//
+// With this simplification, serialization becomes a simple memcpy to
+// the output stream.  Deserialization starts as just a memcpy from
+// the input stream, BUT we then have to write the correct |Display*|
+// into the right field of each X*Event that contains one.
+//
+
+namespace IPC {
+
+template <>
+struct ParamTraits<NPEvent>     // synonym for XEvent
+{
+    typedef NPEvent paramType;
+
+    static void Write(Message* aMsg, const paramType& aParam)
+    {
+        aMsg->WriteBytes(&aParam, sizeof(paramType));
+    }
+
+    static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+    {
+        const char* bytes = 0;
+
+        if (!aMsg->ReadBytes(aIter, &bytes, sizeof(paramType))) {
+            return false;
+        }
+
+        memcpy(aResult, bytes, sizeof(paramType));
+        SetXDisplay(*aResult);
+        return true;
+    }
+
+    static void Log(const paramType& aParam, std::wstring* aLog)
+    {
+        // TODO
+        aLog->append(L"(XEvent)");
+    }
+
+private:
+    static Display* GetXDisplay(const XAnyEvent& ev)
+    {
+        // TODO: get Display* from Window in |ev|
+
+        // FIXME: do this using Xlib, don't use Gdk
+        
+        return GDK_DISPLAY();
+    }
+
+    static Display* GetXDisplay(const XErrorEvent& ev)
+    {
+        // TODO: get Display* from Window in |ev|
+
+        // FIXME: do this using Xlib, don't use Gdk
+        
+        return GDK_DISPLAY();
+    }
+
+    static void SetXDisplay(XEvent& ev)
+    {
+        if (ev.type >= KeyPress) {
+            ev.xany.display = GetXDisplay(ev.xany);
+        }
+        else {
+            // XXX assuming that this is an error event
+            // (type == 0? not clear from Xlib.h)
+            ev.xerror.display = GetXDisplay(ev.xerror);
+        }
+    }
+};
+
+} // namespace IPC
+
+
+#endif // ifndef mozilla_dom_plugins_NPEventX11_h
--- a/dom/plugins/PPluginInstance.ipdl
+++ b/dom/plugins/PPluginInstance.ipdl
@@ -40,16 +40,17 @@
 include protocol "PPluginModule.ipdl";
 include protocol "PPluginScriptableObject.ipdl";
 include protocol "PBrowserStream.ipdl";
 include protocol "PStreamNotify.ipdl";
 
 include "mozilla/plugins/PluginMessageUtils.h";
 
 using NPError;
+using NPEvent;
 using NPWindow;
 using NPReason;
 
 namespace mozilla {
 namespace plugins {
 
 rpc protocol PPluginInstance
 {
@@ -72,16 +73,19 @@ child:
              uint16_t stype);
 
   rpc NPP_SetWindow(NPWindow window)
     returns (NPError rv);
 
   rpc NPP_GetValue_NPPVpluginScriptableNPObject()
     returns (PPluginScriptableObject value, NPError result);
 
+  rpc NPP_HandleEvent(NPEvent event)
+    returns (int16_t handled);
+
 parent:
   rpc NPN_GetValue_NPNVjavascriptEnabledBool()
     returns (bool value, NPError result);
   rpc NPN_GetValue_NPNVisOfflineBool()
     returns (bool value, NPError result);
   rpc NPN_GetValue_NPNVWindowNPObject()
     returns (PPluginScriptableObject value, NPError result);
   rpc NPN_GetValue_NPNVPluginElementNPObject()
--- a/dom/plugins/PluginInstanceChild.cpp
+++ b/dom/plugins/PluginInstanceChild.cpp
@@ -179,16 +179,26 @@ PluginInstanceChild::AnswerNPP_GetValue_
     }
 
     PluginModuleChild::sBrowserFuncs.releaseobject(object);
     *value = actor;
     return true;
 }
 
 bool
+PluginInstanceChild::AnswerNPP_HandleEvent(const NPEvent& event,
+                                           int16_t* handled)
+{
+    // plugins might be fooling with these, make a copy
+    NPEvent evcopy = event;
+    *handled = mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy));
+    return true;
+}
+
+bool
 PluginInstanceChild::AnswerNPP_SetWindow(const NPWindow& aWindow,
                                          NPError* rv)
 {
     printf("[PluginInstanceChild] NPP_SetWindow(%lx, %d, %d)\n",
            reinterpret_cast<unsigned long>(aWindow.window),
            aWindow.width, aWindow.height);
 
 #if defined(OS_LINUX)
--- a/dom/plugins/PluginInstanceChild.h
+++ b/dom/plugins/PluginInstanceChild.h
@@ -68,16 +68,19 @@ protected:
     friend class BrowserStreamChild;
 
     virtual bool AnswerNPP_SetWindow(const NPWindow& window, NPError* rv);
 
     virtual bool
     AnswerNPP_GetValue_NPPVpluginScriptableNPObject(PPluginScriptableObjectChild** value,
                                                     NPError* result);
 
+    virtual bool
+    AnswerNPP_HandleEvent(const NPEvent& event, int16_t* handled);
+
     virtual PPluginScriptableObjectChild*
     PPluginScriptableObjectConstructor();
 
     virtual bool
     PPluginScriptableObjectDestructor(PPluginScriptableObjectChild* aObject);
 
     virtual PBrowserStreamChild*
     PBrowserStreamConstructor(const nsCString& url,
--- a/dom/plugins/PluginInstanceParent.cpp
+++ b/dom/plugins/PluginInstanceParent.cpp
@@ -185,18 +185,17 @@ PluginInstanceParent::PStreamNotifyDestr
 
 NPError
 PluginInstanceParent::NPP_SetWindow(NPWindow* aWindow)
 {
     _MOZ_LOG(__FUNCTION__);
     NS_ENSURE_TRUE(aWindow, NPERR_GENERIC_ERROR);
 
     NPError prv;
-    nsresult rv = CallNPP_SetWindow(*aWindow, &prv);
-    if (NS_OK != rv)
+    if (!CallNPP_SetWindow(*aWindow, &prv))
         return NPERR_GENERIC_ERROR;
     return prv;
 }
 
 NPError
 PluginInstanceParent::NPP_GetValue(NPPVariable variable, void *ret_value)
 {
     _MOZ_LOG(__FUNCTION__);
@@ -219,16 +218,30 @@ PluginInstanceParent::NPP_GetValue(NPPVa
     default:
         return NPERR_GENERIC_ERROR;
     }
 
     NS_NOTREACHED("Don't get here!");
     return NPERR_GENERIC_ERROR;
 }
 
+int16_t
+PluginInstanceParent::NPP_HandleEvent(void* event)
+{
+    _MOZ_LOG(__FUNCTION__);
+
+    int16_t handled;
+    if (!CallNPP_HandleEvent(*reinterpret_cast<NPEvent*>(event),
+                             &handled)) {
+        return 0;               // no good way to handle errors here...
+    }
+
+    return handled;
+}
+
 NPError
 PluginInstanceParent::NPP_NewStream(NPMIMEType type, NPStream* stream,
                                     NPBool seekable, uint16_t* stype)
 {
     _MOZ_LOG(__FUNCTION__);
         
     NPError err;
     CallPBrowserStreamConstructor(new BrowserStreamParent(this, stream),
--- a/dom/plugins/PluginInstanceParent.h
+++ b/dom/plugins/PluginInstanceParent.h
@@ -144,21 +144,17 @@ public:
                           NPBool seekable, uint16_t* stype);
     NPError NPP_DestroyStream(NPStream* stream, NPReason reason);
 
     void NPP_Print(NPPrint* platformPrint)
     {
         _MOZ_LOG(__FUNCTION__);
     }
 
-    int16_t NPP_HandleEvent(void* event)
-    {
-        _MOZ_LOG(__FUNCTION__);
-        return 0;
-    }
+    int16_t NPP_HandleEvent(void* event);
 
     void NPP_URLNotify(const char* url, NPReason reason, void* notifyData)
     {
         _MOZ_LOG(__FUNCTION__);
     }
 
 private:
     NPP mNPP;
--- a/dom/plugins/PluginMessageUtils.h
+++ b/dom/plugins/PluginMessageUtils.h
@@ -420,11 +420,32 @@ struct ParamTraits<mozilla::plugins::IPC
         ReadParam(aMsg, aIter, &p.length)) {
       *aResult = p;
       return true;
     }
     return false;
   }
 };
 
+
 } /* namespace IPC */
 
+
+// Serializing NPEvents is completely platform-specific and can be rather
+// intricate depending on the platform.  So for readability we split it
+// into separate files and have the only macro crud live here.
+// 
+// NB: these guards are based on those where struct NPEvent is defined
+// in npapi.h.  They should be kept in sync.
+#if defined(XP_MACOSX)
+#  include "mozilla/plugins/NPEventOSX.h"
+#elif defined(XP_WIN)
+#  include "mozilla/plugins/NPEventWindows.h"
+#elif defined(XP_OS2)
+#  error Sorry, OS/2 is not supported
+#elif defined(XP_UNIX) && defined(MOZ_X11)
+#  include "mozilla/plugins/NPEventX11.h"
+#else
+#  error Unsupported platform
+#endif
+
+
 #endif /* DOM_PLUGINS_PLUGINMESSAGEUTILS_H */
--- a/dom/plugins/PluginModuleParent.cpp
+++ b/dom/plugins/PluginModuleParent.cpp
@@ -131,35 +131,33 @@ PluginModuleParent::SetPluginFuncs(NPPlu
 #ifdef OS_LINUX
 NPError
 PluginModuleParent::NP_Initialize(const NPNetscapeFuncs* npnIface,
                                  NPPluginFuncs* nppIface)
 {
     _MOZ_LOG(__FUNCTION__);
 
     NPError prv;
-    nsresult rv = CallNP_Initialize(&prv);
-    if (NS_OK != rv)
+    if (!CallNP_Initialize(&prv))
         return NPERR_GENERIC_ERROR;
     else if (NPERR_NO_ERROR != prv)
         return prv;
 
     SetPluginFuncs(nppIface);
     return NPERR_NO_ERROR;
 }
 #else
 NPError
 PluginModuleParent::NP_Initialize(const NPNetscapeFuncs* npnIface)
 {
     _MOZ_LOG(__FUNCTION__);
 
     NPError prv;
-    nsresult rv = CallNP_Initialize(&prv);
-    if (NS_FAILED(rv))
-        return rv;
+    if (!CallNP_Initialize(&prv))
+        return NP_ERR_GENERIC_ERROR;
     return prv;
 }
 
 NPError
 PluginModuleParent::NP_GetEntryPoints(NPPluginFuncs* nppIface)
 {
     NS_ASSERTION(nppIface, "Null pointer!");
 
@@ -218,17 +216,17 @@ PluginModuleParent::NPP_Destroy(NPP inst
     //  (4) free parent
 
     _MOZ_LOG(__FUNCTION__);
 
     PluginInstanceParent* parentInstance =
         static_cast<PluginInstanceParent*>(instance->pdata);
 
     NPError prv;
-    if (Shim::HACK_target->CallPPluginInstanceDestructor(parentInstance, &prv)) {
+    if (!Shim::HACK_target->CallPPluginInstanceDestructor(parentInstance, &prv)) {
         prv = NPERR_GENERIC_ERROR;
     }
     instance->pdata = nsnull;
 
     return prv;
  }
 
 NPIdentifier