[vlc-commits] Work around lack of functional NPN_PluginThreadAsyncCall in Opera on Linux

Cheng Sun git at videolan.org
Wed Dec 28 19:15:55 CET 2011


npapi-vlc | branch: master | Cheng Sun <chengsun9 at gmail.com> | Sat Dec 24 20:32:50 2011 +0000| [338e68c7be5266f2df09668f8cd45e708a3aa7fc] | committer: Jean-Baptiste Kempf

Work around lack of functional NPN_PluginThreadAsyncCall in Opera on Linux

Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

> http://git.videolan.org/gitweb.cgi/npapi-vlc.git/?a=commit;h=338e68c7be5266f2df09668f8cd45e708a3aa7fc
---

 npapi/support/npunix.cpp |   51 +++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/npapi/support/npunix.cpp b/npapi/support/npunix.cpp
index de3e3c0..2c5aacc 100644
--- a/npapi/support/npunix.cpp
+++ b/npapi/support/npunix.cpp
@@ -56,6 +56,7 @@
 #include "npfunctions.h"
 #endif
 
+#include <cstring>
 #include "../vlcshell.h"
 
 /*
@@ -77,6 +78,7 @@
  ***********************************************************************/
 
 static NPNetscapeFuncs   gNetscapeFuncs;    /* Netscape Function table */
+static const char       *gUserAgent;        /* User agent string */
 
 /***********************************************************************
  *
@@ -101,14 +103,56 @@ NPN_Version(int* plugin_major, int* plugin_minor,
     *netscape_minor = gNetscapeFuncs.version & 0xFF;
 }
 
+
+/* in many browsers NPN_PluginThreadAsyncCall is missing/broken */
+
+/* GTK workaround */
+#ifdef USE_GTK
+struct AsyncCallWorkaroundData
+{
+    void (*func)(void *);
+    void *data;
+};
+
+static gboolean AsyncCallWorkaroundCallback(void *userData)
+{
+    AsyncCallWorkaroundData *data = (AsyncCallWorkaroundData *) userData;
+    data->func(data->data);
+    delete data;
+    return false;
+}
+#endif
+
 void
 NPN_PluginThreadAsyncCall(NPP plugin,
                           void (*func)(void *),
                           void *userData)
 {
-#if (((NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR) >= 20)
-    return (*gNetscapeFuncs.pluginthreadasynccall)(plugin, func, userData);
-#endif
+    bool workaround = false;
+
+    const int minor = gNetscapeFuncs.version & 0xFF;
+    if (gUserAgent && (strstr(gUserAgent, "Opera")))
+        workaround = true;
+
+    if (!gNetscapeFuncs.pluginthreadasynccall)
+        workaround = true;
+
+    if (workaround) {
+#       ifdef USE_GTK
+            AsyncCallWorkaroundData *data = new AsyncCallWorkaroundData;
+            data->func = func;
+            data->data = userData;
+            g_idle_add(AsyncCallWorkaroundCallback, (void *)data);
+            return;
+#       endif
+    }
+
+#   if (((NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR) >= 20)
+        return (*gNetscapeFuncs.pluginthreadasynccall)(plugin, func, userData);
+#   endif
+
+    // otherwise nothing we can do...
+    fprintf(stderr, "WARNING: could not call NPN_PluginThreadAsyncCall\n");
 }
 
 NPError
@@ -649,6 +693,7 @@ Private_New(NPMIMEType pluginType, NPP instance, uint16_t mode,
 {
     NPError ret;
     PLUGINDEBUGSTR("New");
+    gUserAgent = NPN_UserAgent(instance);
     ret = NPP_New(pluginType, instance, mode, argc, argn, argv, saved);
     return ret; 
 }



More information about the vlc-commits mailing list