gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] /srv/bzr/gnash/trunk r12140: add a greatly enhanced versi


From: Rob Savoye
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r12140: add a greatly enhanced version of patch #6821, for scriptable support in the plugin.
Date: Thu, 08 Apr 2010 17:11:33 -0600
User-agent: Bazaar (2.0.3)

------------------------------------------------------------
revno: 12140 [merge]
committer: Rob Savoye <address@hidden>
branch nick: trunk
timestamp: Thu 2010-04-08 17:11:33 -0600
message:
  add a greatly enhanced version of patch #6821, for scriptable support in the 
plugin.
added:
  plugin/npapi/pluginScriptObject.cpp
  plugin/npapi/pluginScriptObject.h
  plugin/npapi/scriptable-test.html
modified:
  configure.ac
  plugin/npapi/Makefile.am
  plugin/npapi/plugin.cpp
  plugin/npapi/plugin.h
=== modified file 'configure.ac'
--- a/configure.ac      2010-04-05 20:08:38 +0000
+++ b/configure.ac      2010-04-07 23:48:50 +0000
@@ -283,6 +283,19 @@
     AC_DEFINE(ENABLE_AVM2, [1], [Enable AVM2 code])
 fi
 
+AC_ARG_ENABLE(scriptable,
+  AC_HELP_STRING([--enable-scriptable], [Enable support for AS3]),
+  [case "${enableval}" in
+    yes) scriptable=yes ;;
+    no)  scriptable=no ;;
+    *)   AC_MSG_ERROR([bad value ${enableval} for enable-scriptable option]) ;;
+  esac], scriptable=yes
+)
+AM_CONDITIONAL(SCRIPTABLE, [test x"$scriptable" = xyes])
+if test x$scriptable = xyes; then
+    AC_DEFINE(ENABLE_SCRIPTABLE, [1], [Enable scriptable code in plugin])
+fi
+
 dnl This option is only used if you want Gnash to interwork with 
 dnl the Adobe player using the LocalConnection class.
 dnl lckey=0xdd3adabd

=== modified file 'plugin/npapi/Makefile.am'
--- a/plugin/npapi/Makefile.am  2010-03-25 01:10:34 +0000
+++ b/plugin/npapi/Makefile.am  2010-04-07 23:49:20 +0000
@@ -66,6 +66,12 @@
        $(GLIB_LIBS) \
        $(NULL)
 
+# Scriptable plugin support
+if SCRIPTABLE
+noinst_HEADERS += pluginScriptObject.h
+libgnashplugin_la_SOURCES += pluginScriptObject.cpp
+endif
+
 if PLUGIN_LINK_UNDEFINED
 libgnashplugin_la_LDFLAGS = -avoid-version -L$(plugindir)
 else

=== modified file 'plugin/npapi/plugin.cpp'
--- a/plugin/npapi/plugin.cpp   2010-04-03 15:25:49 +0000
+++ b/plugin/npapi/plugin.cpp   2010-04-08 23:11:33 +0000
@@ -57,7 +57,7 @@
 //  1: fatal errors (errors preventing the plugin from working as it should)
 //  2: informational messages
 //
-#define GNASH_PLUGIN_DEBUG 1
+#define GNASH_PLUGIN_DEBUG 2
 //#define WRITE_FILE
 
 #include "plugin.h" 
@@ -87,6 +87,10 @@
 #define PATH_MAX 1024
 #endif
 
+// For scriptable plugin support
+#ifdef ENABLE_SCRIPTABLE
+#include "pluginScriptObject.h"
+#endif
 extern NPNetscapeFuncs NPNFuncs;
 
 NPBool plugInitialized = FALSE;
@@ -95,8 +99,8 @@
 static bool createSaLauncher = false;
 
 static const char* getPluginDescription();
-static void logDebug(const std::string& msg);
-static void logError(const std::string& msg);
+void GnashLogDebug(const std::string& msg);
+void GnashLogError(const std::string& msg);
 
 
 /// \brief Return the MIME Type description for this plugin.
@@ -120,11 +124,11 @@
 NS_PluginInitialize()
 {
     if ( plugInitialized ) {
-        logDebug("NS_PluginInitialize called, but ignored (we already 
initialized)");
+        GnashLogDebug("NS_PluginInitialize called, but ignored (we already 
initialized)");
         return NPERR_NO_ERROR;
     }
 
-    logDebug("NS_PluginInitialize call 
---------------------------------------------------");
+    GnashLogDebug("NS_PluginInitialize call 
---------------------------------------------------");
 
     /* Browser Functionality Checks */
 
@@ -137,16 +141,14 @@
     XEmbed is not found.
     */    
     
-    err = NPN_GetValue(NULL,
-                NPNVSupportsXEmbedBool,
-                (void *)&supportsXEmbed);
-
+    err = NPN_GetValue(NULL,NPNVSupportsXEmbedBool,
+                       (void *)&supportsXEmbed);
 
     if (err != NPERR_NO_ERROR || !supportsXEmbed) {
-        logError("NPAPI ERROR: No xEmbed support in this browser!");
+        GnashLogError("NPAPI ERROR: No xEmbed support in this browser!");
         return NPERR_INCOMPATIBLE_VERSION_ERROR;
     } else {
-        logDebug("xEmbed supported in this browser");
+        GnashLogDebug("xEmbed supported in this browser");
     }
 
     // GTK is not strictly required, but we do use the Glib main event loop,
@@ -160,7 +162,7 @@
             " Have version " << (int)toolkit << std::endl;
 #endif
     } else {
-        logDebug("GTK2 supported in this browser");
+        GnashLogDebug("GTK2 supported in this browser");
     }
 
     /*
@@ -168,7 +170,7 @@
     */
     char* opts = std::getenv("GNASH_OPTIONS");
     if (opts != NULL) {
-        logDebug(std::string("GNASH_OPTIONS : ") + std::string(opts));
+        GnashLogDebug(std::string("GNASH_OPTIONS : ") + std::string(opts));
         
         // Should the plugin wait for gdb to be attached?
         if ( strstr(opts, "waitforgdb") ) {
@@ -213,7 +215,7 @@
     if ( putenv(gnashrc) ) {
         std::cout << "WARNING: NPAPI plugin could not append to the GNASHRC 
env variable" << std::endl;
     }
-    else logDebug(std::string("NOTE: NPAPI plugin set GNASHRC to ") + 
newGnashRc);
+    else GnashLogDebug(std::string("NOTE: NPAPI plugin set GNASHRC to ") + 
newGnashRc);
 
     /* Success */
 
@@ -256,34 +258,33 @@
     NPError err = NPERR_NO_ERROR;
 
     switch (aVariable) {
-        case NPPVpluginNameString:
-            *static_cast<const char **> (aValue) = PLUGIN_NAME;
-            break;
-
-        // This becomes the description field you see below the opening
-        // text when you type about:plugins and in
-        // navigator.plugins["Shockwave Flash"].description, used in
-        // many flash version detection scripts.
-        case NPPVpluginDescriptionString:
-            *static_cast<const char **>(aValue) =
-                        getPluginDescription();
-            break;
-
-        case NPPVpluginNeedsXEmbed:
+      case NPPVpluginNameString:
+          *static_cast<const char **> (aValue) = PLUGIN_NAME;
+          break;
+          
+          // This becomes the description field you see below the opening
+          // text when you type about:plugins and in
+          // navigator.plugins["Shockwave Flash"].description, used in
+          // many flash version detection scripts.
+      case NPPVpluginDescriptionString:
+          *static_cast<const char **>(aValue) = getPluginDescription();
+          break;
+          
+      case NPPVpluginNeedsXEmbed:
 #ifdef HAVE_GTK2
-            *static_cast<NPBool *>(aValue) = TRUE;
+          *static_cast<NPBool *>(aValue) = TRUE;
 #else
-            *static_cast<NPBool *>(aValue) = FALSE;
+          *static_cast<NPBool *>(aValue) = FALSE;
 #endif
-            break;
-
-        case NPPVpluginTimerInterval:
-
-        case NPPVpluginKeepLibraryInMemory:
-
-        default:
-            err = NPERR_INVALID_PARAM;
-            break;
+          break;
+
+      case NPPVpluginTimerInterval:
+          
+      case NPPVpluginKeepLibraryInMemory:
+          
+      default:
+          err = NPERR_INVALID_PARAM;
+          break;
     }
     return err;
 }
@@ -295,7 +296,9 @@
 nsPluginInstanceBase *
 NS_NewPluginInstance(nsPluginCreateData * aCreateDataStruct)
 {
-    if(!aCreateDataStruct) return NULL;
+    if(!aCreateDataStruct) {
+        return NULL;
+    }
 
     return new nsPluginInstance(aCreateDataStruct);
 }
@@ -329,8 +332,7 @@
     _filefd(-1),
     _name()
 {
-    for (size_t i=0, n=data->argc; i<n; ++i)
-    {
+    for (size_t i=0, n=data->argc; i<n; ++i) {
         std::string name, val;
         gnash::StringNoCaseEqual noCaseCompare;
 
@@ -349,6 +351,9 @@
         _params[name] = val;
     }
 
+#ifdef ENABLE_SCRIPTABLE
+    _scriptObject = NPNFuncs.createobject(_instance, 
GnashPluginScriptObject::marshalGetNPClass());
+#endif
 }
 
 gboolean
@@ -361,7 +366,7 @@
 
     if (rv <= 0) {
         // The child process has not exited; it may be deadlocked. Kill it.
-        logError("BUG: Child process is stuck. Killing it.");
+        GnashLogError("BUG: Child process is stuck. Killing it.");
 
         kill(*pid, SIGKILL);
         waitpid(*pid, &status, 0);
@@ -379,7 +384,7 @@
 /// \brief Destructor
 nsPluginInstance::~nsPluginInstance()
 {
-    logDebug("plugin instance destruction");
+    GnashLogDebug("plugin instance destruction");
 
     if ( _ichanWatchId ) {
         g_source_remove(_ichanWatchId);
@@ -417,7 +422,7 @@
 nsPluginInstance::init(NPWindow* aWindow)
 {
     if(!aWindow) {
-        logError(std::string(__PRETTY_FUNCTION__) + " ERROR: Window handle was 
bogus!");
+        GnashLogError(std::string(__PRETTY_FUNCTION__) + " ERROR: Window 
handle was bogus!");
         return FALSE;
     } else {
 #if GNASH_PLUGIN_DEBUG > 1
@@ -441,7 +446,7 @@
 void
 nsPluginInstance::shut()
 {
-    logDebug("Gnash plugin shutting down");
+    GnashLogDebug("Gnash plugin shutting down");
 
     if (_streamfd != -1) {
         if (close(_streamfd) == -1) {
@@ -453,7 +458,7 @@
 
     int ret = close(_controlfd);
     if (ret != 0) {
-        logDebug("Gnash plugin failed to close the control socket!");
+        GnashLogDebug("Gnash plugin failed to close the control socket!");
     }
 }
 /// \brief Set the window to be used to render in
@@ -467,7 +472,7 @@
 nsPluginInstance::SetWindow(NPWindow* aWindow)
 {
     if(!aWindow) {
-        logError(std::string(__FUNCTION__) + ": ERROR: Window handle was 
bogus!");
+        GnashLogError(std::string(__FUNCTION__) + ": ERROR: Window handle was 
bogus!");
         return NPERR_INVALID_PARAM;
 #if 0
     } else {
@@ -499,9 +504,36 @@
 NPError
 nsPluginInstance::GetValue(NPPVariable aVariable, void *aValue)
 {
+    if (aVariable == NPPVpluginScriptableNPObject) {
+        if (_scriptObject) {
+            void **v = (void **)aValue;
+            NPNFuncs.retainobject(_scriptObject);
+            *v = _scriptObject;
+        } else {
+            GnashLogDebug("_scriptObject is not assigned");
+        }
+    }
+
     return NS_PluginGetValue(aVariable, aValue);
 }
 
+#if 0
+// FIXME: debugging stuff, will be gone soon after I figure how this works
+void myfunc(void */* param */)
+{
+    GnashLogDebug("Here I am!!!\n");
+}
+
+// Call a JavaScript method from the plugin
+void
+NPN_PluginThreadAsyncCall(NPP plugin, void (*func)(void *), void *userData)
+{
+#if (((NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR) >= 20)
+    return (*NPNFuncs.pluginthreadasynccall)(plugin, func, userData);
+#endif
+}
+#endif
+
 /// \brief Open a new data stream
 ///
 /// Opens a new incoming data stream, which is the flash movie we want
@@ -510,8 +542,7 @@
 /// 
http://www.shockwave.com/swf/navbar/navbar_sw.swf?atomfilms=http%3a//www.atomfilms.com/af/home/&shockwave=http%3a//www.shockwave.com&gameblast=http%3a//gameblast.shockwave.com/gb/gbHome.jsp&known=0
 /// 
../flash/gui.swf?ip_addr=foobar.com&ip_port=3660&show_cursor=true&path_prefix=../flash/&trapallkeys=true"
 ///
-/// So this is where we parse the URL to get all the options passed in
-/// when invoking the plugin.
+
 NPError
 nsPluginInstance::NewStream(NPMIMEType /*type*/, NPStream* stream,
                             NPBool /*seekable*/, uint16_t* /*stype*/)
@@ -525,6 +556,13 @@
     }
     _swf_url = stream->url;
 
+#if 0
+    // FIXME: debugging crap for now call javascript
+    NPN_PluginThreadAsyncCall(_instance, myfunc, NULL);
+//    printf("FIXME: %s", getEmbedURL());
+#endif
+    
+    
 #if GNASH_PLUGIN_DEBUG > 1
     std::cout << __FUNCTION__ << ": The full URL is " << _swf_url << std::endl;
 #endif
@@ -537,7 +575,7 @@
     fname = "/tmp/";
     fname += _swf_url.substr(start, end - start);
 
-    logDebug("The Flash movie name is: " + fname);
+    GnashLogDebug("The Flash movie name is: " + fname);
 
     _filefd = open(fname.c_str(),
             O_CREAT | O_WRONLY,
@@ -622,7 +660,7 @@
 nsPluginInstance::handlePlayerRequests(GIOChannel* iochan, GIOCondition cond)
 {
     if ( cond & G_IO_HUP ) {
-        logDebug("Player request channel hang up");
+        GnashLogDebug("Player request channel hang up");
         // Returning false here will cause the "watch" to be removed. This 
watch
         // is the only reference held to the GIOChannel, so it will be
         // destroyed. We must make sure we don't attempt to destroy it again.
@@ -646,22 +684,22 @@
 
         switch ( status ) {
             case G_IO_STATUS_ERROR:
-                logError(std::string("Error reading request line: ") + 
error->message);
+                GnashLogError(std::string("Error reading request line: ") + 
error->message);
 
                 g_error_free(error);
                 return false;
             case G_IO_STATUS_EOF:
-                logError(std::string("EOF (error: ") + error->message);
+                GnashLogError(std::string("EOF (error: ") + error->message);
                 return false;
             case G_IO_STATUS_AGAIN:
-                logError(std::string("Read again(error: ") + error->message);
+                GnashLogError(std::string("Read again(error: ") + 
error->message);
                 break;
             case G_IO_STATUS_NORMAL:
                 // process request
-                logDebug("Normal read: " + std::string(request));
+                GnashLogDebug("Normal read: " + std::string(request));
                 break;
             default:
-                logError("Abnormal status!");
+                GnashLogError("Abnormal status!");
                 return false;
             
         }
@@ -680,7 +718,7 @@
 nsPluginInstance::processPlayerRequest(gchar* buf, gsize linelen)
 {
     if ( linelen < 4 ) {
-        logError(std::string("Invalid player request (too short): ") +  buf);
+        GnashLogError(std::string("Invalid player request (too short): ") +  
buf);
         return false;
     }
 
@@ -688,7 +726,7 @@
         char* target = buf + 4;
         if ( ! *target )
         {
-            logError("No target found after GET request");
+            GnashLogError("No target found after GET request");
             return false;
         }
         char* url = target;
@@ -697,7 +735,7 @@
             *url='\0';
             ++url;
         } else {
-            logError("No colon found after GETURL target string");
+            GnashLogError("No colon found after GETURL target string");
             return false;
         }
 
@@ -711,7 +749,7 @@
     } else if ( ! std::strncmp(buf, "INVOKE ", 7) ) {
         char* command = buf + 7;
         if ( ! *command ) {
-            logError("No command found after INVOKE request");
+            GnashLogError("No command found after INVOKE request");
             return false;
         }
         char* arg = command;
@@ -720,7 +758,7 @@
             *arg='\0';
             ++arg;
         } else {
-            logError("No colon found after INVOKE command string");
+            GnashLogError("No colon found after INVOKE command string");
             return false;
         }
 
@@ -732,7 +770,7 @@
         // TODO: check if _self is a good target for this
         static const char* tgt = "_self";
 
-        logDebug("Calling NPN_GetURL(" + jsurl.str() + ", '" + 
std::string(tgt) + "');");
+        GnashLogDebug("Calling NPN_GetURL(" + jsurl.str() + ", '" + 
std::string(tgt) + "');");
 
         NPN_GetURL(_instance, jsurl.str().c_str(), tgt);
         return true;
@@ -748,7 +786,7 @@
         }
         else
         {
-            logError("No colon found after getURL postdata string");
+            GnashLogError("No colon found after getURL postdata string");
             return false;
         }
         
@@ -758,7 +796,7 @@
             *url='\0';
             ++url;
         } else {
-            logError("No $ character found after getURL target string");
+            GnashLogError("No $ character found after getURL target string");
             return false;
         }
         
@@ -768,13 +806,13 @@
 
         return true;
     } else {
-        logError("Unknown player request: " + std::string(buf));
+        GnashLogError("Unknown player request: " + std::string(buf));
         return false;
     }
 }
 
 void
-logDebug(const std::string& msg)
+GnashLogDebug(const std::string& msg)
 {
 #if GNASH_PLUGIN_DEBUG > 1
     std::cout << msg << std::endl;
@@ -784,7 +822,7 @@
 }
 
 void
-logError(const std::string& msg)
+GnashLogError(const std::string& msg)
 {
 #ifdef GNASH_PLUGIN_DEBUG
     std::cout << msg << std::endl;
@@ -804,7 +842,7 @@
         procname = gnash_env;
         process_found = (0 == stat(procname.c_str(), &procstats));
         if (!process_found) {
-            logError("Invalid path to gnash executable: ");
+            GnashLogError("Invalid path to gnash executable: ");
             return "";
         }
     }
@@ -819,7 +857,7 @@
     }
 
     if (!process_found) {
-        logError(std::string("Unable to find Gnash in ") + GNASHBINDIR);
+        GnashLogError(std::string("Unable to find Gnash in ") + GNASHBINDIR);
         return "";
     }
 
@@ -845,7 +883,7 @@
     saLauncher.open(ss.str().c_str(), std::ios::out | std::ios::trunc);
 
     if (!saLauncher) {
-        logError("Failed to open new file for standalone launcher: " + 
ss.str());
+        GnashLogError("Failed to open new file for standalone launcher: " + 
ss.str());
         return;
     }
 
@@ -878,17 +916,17 @@
 
     std::string cmd = getGnashExecutable();
     if (cmd.empty()) {
-        logError("Failed to locate the Gnash executable!");
+        GnashLogError("Failed to locate the Gnash executable!");
         return arg_vec;
     }
     arg_vec.push_back(cmd);
 
     arg_vec.push_back("-u");
     arg_vec.push_back(_swf_url);
-
+    
     const char* pageurl = getCurrentPageURL();
     if (!pageurl) {
-        logError("Could not get current page URL!");
+        GnashLogError("Could not get current page URL!");
     } else {
         arg_vec.push_back("-U");
         arg_vec.push_back(pageurl);
@@ -979,20 +1017,20 @@
     
     int ret = pipe(p2c_pipe);
     if (ret == -1) {
-        logError("ERROR: parent to child pipe() failed: " +
+        GnashLogError("ERROR: parent to child pipe() failed: " +
                  std::string(std::strerror(errno)));
     }
     _streamfd = p2c_pipe[1];
 
     ret = pipe(c2p_pipe);
     if (ret == -1) {
-        logError("ERROR: child to parent pipe() failed: " +
+        GnashLogError("ERROR: child to parent pipe() failed: " +
                  std::string(std::strerror(errno)));
     }
 
     ret = pipe(p2c_controlpipe);
     if (ret == -1) {
-        logError("ERROR: parent to child pipe() failed: " +
+        GnashLogError("ERROR: parent to child pipe() failed: " +
                  std::string(std::strerror(errno)));
     }
 
@@ -1004,7 +1042,7 @@
 
     std::vector<std::string> arg_vec = getCmdLine(c2p_pipe[1], 
p2c_controlpipe[0]);
     if (arg_vec.empty()) {
-        logError("Failed to obtain command line parameters.");
+        GnashLogError("Failed to obtain command line parameters.");
         return;
     }
 
@@ -1022,7 +1060,7 @@
 
     // If the fork failed, childpid is -1. So print out an error message.
     if (_childpid == -1) {
-        logError("ERROR: dup2() failed: " + std::string(strerror(errno)));
+        GnashLogError("ERROR: dup2() failed: " + std::string(strerror(errno)));
         return;
     }
 
@@ -1032,14 +1070,14 @@
         // we want to write to p2c pipe, so close read-fd0
         ret = close (p2c_pipe[0]);
         if (ret == -1) {
-            logError("ERROR: p2c_pipe[0] close() failed: " +
+            GnashLogError("ERROR: p2c_pipe[0] close() failed: " +
                      std::string(strerror(errno)));
         }
 
         // we want to read from c2p pipe, so close write-fd1
         ret = close (c2p_pipe[1]);
         if (ret == -1) {
-            logError("ERROR: c2p_pipe[1] close() failed: " + 
+            GnashLogError("ERROR: c2p_pipe[1] close() failed: " + 
                      std::string(strerror(errno)));
         }
 
@@ -1070,7 +1108,7 @@
     ret = dup2 (p2c_pipe[0], fileno(stdin));
     
     if (ret == -1) {
-        logError("ERROR: dup2() failed: " + std::string(strerror(errno)));
+        GnashLogError("ERROR: dup2() failed: " + std::string(strerror(errno)));
     }
 
     // Close all of the browser's file descriptors that we just inherited
@@ -1111,7 +1149,7 @@
     NPN_ReleaseObject(window);
 
     if (!NPVARIANT_IS_OBJECT(vDoc)) {
-        logError("Can't get window object");
+        GnashLogError("Can't get window object");
         return NULL;
     }
     
@@ -1123,7 +1161,7 @@
     NPN_ReleaseObject(npDoc);
 
     if (!NPVARIANT_IS_OBJECT(vLoc)) {
-        logError("Can't get window.location object");
+        GnashLogError("Can't get window.location object");
         return NULL;
     }
 
@@ -1135,7 +1173,55 @@
     NPN_ReleaseObject(npLoc);
 
     if (!NPVARIANT_IS_STRING(vProp)) {
-        logError("Can't get window.location.href object");
+        GnashLogError("Can't get window.location.href object");
+        return NULL;
+    }
+
+    const NPString& propValue = NPVARIANT_TO_STRING(vProp);
+
+    return propValue.UTF8Characters; // const char *
+}
+
+const char*
+nsPluginInstance::getEmbedURL() const
+{
+    NPP npp = _instance;
+
+    NPIdentifier sDocument = NPN_GetStringIdentifier("document");
+
+    NPObject *window;
+    NPN_GetValue(npp, NPNVWindowNPObject, &window);
+
+    NPVariant vDoc;
+    NPN_GetProperty(npp, window, sDocument, &vDoc);
+    NPN_ReleaseObject(window);
+
+    if (!NPVARIANT_IS_OBJECT(vDoc)) {
+        GnashLogError("Can't get document object");
+        return NULL;
+    }
+    
+    NPObject* npDoc = NPVARIANT_TO_OBJECT(vDoc);
+
+    NPIdentifier sLocation = NPN_GetStringIdentifier("yt");
+    NPVariant vLoc;
+    NPN_GetProperty(npp, npDoc, sLocation, &vLoc);
+    NPN_ReleaseObject(npDoc);
+
+    if (!NPVARIANT_IS_OBJECT(vLoc)) {
+        GnashLogError("Can't get document.yt object");
+        return NULL;
+    }
+
+    NPObject* npLoc = NPVARIANT_TO_OBJECT(vLoc);
+
+    NPIdentifier sProperty = NPN_GetStringIdentifier("config_");
+    NPVariant vProp;
+    NPN_GetProperty(npp, npLoc, sProperty, &vProp);
+    NPN_ReleaseObject(npLoc);
+
+    if (!NPVARIANT_IS_STRING(vProp)) {
+        GnashLogError("Can't get document.yt.config_ object");
         return NULL;
     }
 
@@ -1157,5 +1243,5 @@
 
 // Local Variables:
 // mode: C++
-// indent-tabs-mode: t
+// indent-tabs-mode: nil
 // End:

=== modified file 'plugin/npapi/plugin.h'
--- a/plugin/npapi/plugin.h     2010-03-24 23:33:22 +0000
+++ b/plugin/npapi/plugin.h     2010-04-08 19:42:32 +0000
@@ -56,7 +56,7 @@
 public:
     nsPluginInstance(nsPluginCreateData* );
     virtual ~nsPluginInstance();
-
+    
     // We are required to implement these three methods.
     NPBool init(NPWindow *aWindow);
     NPBool isInitialized() { return plugInitialized; }
@@ -71,7 +71,11 @@
 
     int32_t WriteReady(NPStream *stream);
     int32_t Write(NPStream *stream, int32_t offset, int32_t len, void *buffer);
-
+#ifdef ENABLE_SCRIPTABLE
+    NPObject *getScriptableObject();
+    const char *getEmbedURL() const;
+#endif
+    
 private:
     void startProc();
     std::vector<std::string> getCmdLine(int hostfd, int controlfd);
@@ -113,13 +117,17 @@
 
     /// Name of the plugin instance element in the dom 
     std::string                        _name;
-
+#ifdef ENABLE_SCRIPTABLE
+    NPObject                            *_scriptObject;
+#endif
+    
     const char* getCurrentPageURL() const;
 };
 
 // end of __PLUGIN_H__
 #endif
 
-// Local Variables:
+// local Variables:
 // mode: C++
+// indent-tabs-mode: nil
 // End:

=== added file 'plugin/npapi/pluginScriptObject.cpp'
--- a/plugin/npapi/pluginScriptObject.cpp       1970-01-01 00:00:00 +0000
+++ b/plugin/npapi/pluginScriptObject.cpp       2010-04-08 22:39:09 +0000
@@ -0,0 +1,525 @@
+// 
+//   Copyright (C) 2010 Free Software Foundation, Inc
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <map>
+
+#include "npapi.h"
+#include "npruntime.h"
+#include "plugin.h" 
+#include "pluginScriptObject.h"
+
+extern NPNetscapeFuncs NPNFuncs;
+
+// Debugging utilities
+extern void GnashLogDebug(const std::string& msg);
+extern void GnashLogError(const std::string& msg);
+
+// NPClass of GnashPluginScriptObject
+static NPClass GnashPluginScriptObjectClass = {
+    NP_CLASS_STRUCT_VERSION,
+    GnashPluginScriptObject::marshalAllocate,
+    GnashPluginScriptObject::marshalDeallocate,
+    GnashPluginScriptObject::marshalInvalidate,
+    GnashPluginScriptObject::marshalHasMethod,
+    GnashPluginScriptObject::marshalInvoke,
+    GnashPluginScriptObject::marshalInvokeDefault,
+    GnashPluginScriptObject::marshalHasProperty,
+    GnashPluginScriptObject::marshalGetProperty,
+    GnashPluginScriptObject::marshalSetProperty,
+    GnashPluginScriptObject::marshalRemoveProperty
+};
+
+#if 0
+
+#define NUM_METHOD_IDENTIFIERS       3
+static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
+static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
+   "setVariable",
+   "getVariable",
+   "showFoobar"
+};
+#endif
+
+bool
+testfunc (NPObject */* npobj */, NPIdentifier /* name */, const NPVariant 
*/*args */,
+          uint32_t /* argCount */, NPVariant *result)
+{   
+    GnashLogDebug(__PRETTY_FUNCTION__);
+    
+    DOUBLE_TO_NPVARIANT(122333.4444, *result);
+    
+    return true;
+}
+
+void
+GnashPluginScriptObject::AddProperty(const std::string &name,
+                                     const std::string &str)
+{
+    NPIdentifier id = NPN_GetStringIdentifier(name.c_str());
+    NPVariant *value = new NPVariant;
+    int length = str.size();;
+    char *bar = new char[length+1];
+    std::copy(str.begin(), str.end(), bar);
+    STRINGN_TO_NPVARIANT(bar, length, *value);
+    SetProperty(id, value);
+}
+
+void
+GnashPluginScriptObject::AddProperty(const std::string &name, double num)
+{
+    NPIdentifier id = NPN_GetStringIdentifier(name.c_str());
+    NPVariant *value = new NPVariant;
+    DOUBLE_TO_NPVARIANT(num, *value);
+    SetProperty(id, value);
+}
+
+void
+GnashPluginScriptObject::AddProperty(const std::string &name, int num)
+{
+    NPIdentifier id = NPN_GetStringIdentifier(name.c_str());
+    NPVariant *value = new NPVariant;
+    INT32_TO_NPVARIANT(num, *value);
+    SetProperty(id, value);
+}
+
+// Sets up the property and method identifier arrays used by the browser
+// via the hasProperty and hasMethod fuction pointers
+void
+GnashPluginScriptObject::initializeIdentifiers()
+{
+    GnashLogDebug("initializeIdentifiers");
+
+    AddProperty("src", "example");
+    AddProperty("align", "middle");
+    AddProperty("quality", "high");
+    AddProperty("bgcolor", "#FFFFFF");
+    AddProperty("allowScriptAccess", "sameDomain");
+    AddProperty("type", "application/x-shockwave-flash");
+    AddProperty("codebase", "http://www.getgnash.org";);
+    AddProperty("pluginspage", "http://www.getgnash.org";);
+
+    AddProperty("classid", "unneeded for free software");
+    AddProperty("movie", "unknown");
+    AddProperty("id", "id unknown");
+    AddProperty("width", 0);
+    AddProperty("height", 0);
+    AddProperty("vspace", 0);
+    AddProperty("hspace", 0);
+    AddProperty("class", "class unknown");
+    AddProperty("title", "title unknown");
+    AddProperty("accesskey", 0);
+    AddProperty("name", "name unknown");
+    AddProperty("tabindex", 8);
+    AddProperty("FlashVars", "flashVars unknown");
+
+    // Javascript and flash events
+    AddProperty("onafterupdate", "unknown");
+    AddProperty("onbeforeupdate", "unknown");
+    AddProperty("onblur", "unknown");
+    AddProperty("oncellchange", "unknown");
+    AddProperty("onclick", "unknown");
+    AddProperty("ondblClick", "unknown");
+    AddProperty("ondrag", "unknown");
+    AddProperty("ondragend", "unknown");
+    AddProperty("ondragenter", "unknown");
+    AddProperty("ondragleave", "unknown");
+    AddProperty("ondragover", "unknown");
+    AddProperty("ondrop", "unknown");
+    AddProperty("onfinish", "unknown");
+    AddProperty("onfocus", "unknown");
+    AddProperty("onhelp", "unknown");
+    AddProperty("onmousedown", "unknown");
+    AddProperty("onmouseup", "unknown");
+    AddProperty("onmouseover", "unknown");
+    AddProperty("onmousemove", "unknown");
+    AddProperty("onmouseout", "unknown");
+    AddProperty("onkeypress", "unknown");
+    AddProperty("onkeydown", "unknown");
+    AddProperty("onkeyup", "unknown");
+    AddProperty("onload", "unknown");
+    AddProperty("onlosecapture", "unknown");
+    AddProperty("onpropertychange", "unknown");
+    AddProperty("onreadystatechange", "unknown");
+    AddProperty("onrowsdelete", "unknown");
+    AddProperty("onrowenter", "unknown");
+    AddProperty("onrowexit", "unknown");
+    AddProperty("onrowsinserted", "unknown");
+    AddProperty("onstart", "");
+    AddProperty("onscroll", "unknown");
+    AddProperty("onbeforeeditfocus", "unknown");
+    AddProperty("onactivate", "unknown");
+    AddProperty("onbeforedeactivate", "unknown");
+    AddProperty("ondeactivate", "unknown");
+
+#if 0
+   for (int i = 0; i < NUM_METHOD_IDENTIFIERS; i++) {
+       SetProperty(pluginMethodIdentifiers[i], value);
+   }
+   
+   // fill the method identifier array
+   NPNFuncs.getstringidentifiers(pluginMethodIdentifierNames,
+                                 NUM_METHOD_IDENTIFIERS,
+                                 pluginMethodIdentifiers);
+#endif
+   // We maintain an internal property for our version number, rather
+   // than asking the player.
+   AddProperty("version", 456.789);
+   AddProperty("hello", "Hello World");
+   
+   NPIdentifier fid = NPN_GetStringIdentifier("showFoobar");
+   NPInvokeFunctionPtr func = testfunc;
+   
+   AddMethod(fid, func);
+
+};
+
+// Constructor
+GnashPluginScriptObject::GnashPluginScriptObject()
+    : _nppinstance (0)
+{
+//    GnashLogDebug(__PRETTY_FUNCTION__);
+    initializeIdentifiers();
+}
+
+// Constructor
+GnashPluginScriptObject::GnashPluginScriptObject(NPP npp)
+    : _nppinstance (npp)
+{
+//    GnashLogDebug(__PRETTY_FUNCTION__);
+    initializeIdentifiers();
+}
+
+// Destructor
+GnashPluginScriptObject::~GnashPluginScriptObject() 
+{
+    // GnashLogDebug(__PRETTY_FUNCTION__);
+    // do nothing
+}
+
+// Marshal Functions
+NPClass *
+GnashPluginScriptObject::marshalGetNPClass() 
+{
+    // GnashLogDebug(__PRETTY_FUNCTION__);
+    return &GnashPluginScriptObjectClass;
+}
+
+NPObject *
+GnashPluginScriptObject::marshalAllocate (NPP npp, NPClass */* aClass */)
+{
+    GnashLogDebug(__PRETTY_FUNCTION__);
+    return new GnashPluginScriptObject(npp);
+}
+
+
+void 
+GnashPluginScriptObject::marshalDeallocate (NPObject *npobj)
+{
+    GnashLogDebug(__PRETTY_FUNCTION__);
+//    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+//    gpso->Deallocate();
+    delete (GnashPluginScriptObject *)npobj;
+}
+
+void 
+GnashPluginScriptObject::marshalInvalidate (NPObject *npobj)
+{
+    GnashLogDebug(__PRETTY_FUNCTION__);
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+//    gpso->Invalidate();
+}
+
+bool 
+GnashPluginScriptObject::marshalHasMethod (NPObject *npobj, NPIdentifier name)
+{
+    // GnashLogDebug(__PRETTY_FUNCTION__);
+
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+#if 0
+    printf("Checking for Method: ");
+    if (NPN_IdentifierIsString(name)) {
+        printf("%s\n", NPN_UTF8FromIdentifier(name));
+    } else {
+        printf("%d\n", NPN_IntFromIdentifier(name));
+    }
+#endif
+    
+    return gpso->HasMethod(name);
+}
+
+bool 
+GnashPluginScriptObject::marshalInvoke (NPObject *npobj, NPIdentifier name,
+                                        const NPVariant *args, uint32_t 
argCount,
+                                        NPVariant *result)
+{
+    // GnashLogDebug(__PRETTY_FUNCTION__);
+    
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+    
+    return gpso->Invoke(name, args, argCount, result);
+}
+
+bool 
+GnashPluginScriptObject::marshalInvokeDefault (NPObject *npobj,
+                                               const NPVariant *args,
+                                               uint32_t argCount,
+                                               NPVariant *result)
+{
+    // GnashLogDebug(__PRETTY_FUNCTION__);
+
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+    
+    return gpso->InvokeDefault(args, argCount, result);
+}
+
+bool 
+GnashPluginScriptObject::marshalHasProperty (NPObject *npobj, NPIdentifier 
name)
+{
+//    GnashLogDebug(__PRETTY_FUNCTION__);
+    
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+    return gpso->HasProperty(name);
+}
+
+bool 
+GnashPluginScriptObject::marshalGetProperty (NPObject *npobj, NPIdentifier 
name,
+                                             NPVariant *result)
+{
+//    GnashLogDebug(__PRETTY_FUNCTION__);
+
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+    
+    return gpso->GetProperty(name, result);    
+}
+
+bool 
+GnashPluginScriptObject::marshalSetProperty (NPObject *npobj, NPIdentifier 
name,
+                                             const NPVariant *value)
+{
+//    GnashLogDebug(__PRETTY_FUNCTION__);
+
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;    
+    return gpso->SetProperty(name, value);
+}
+
+bool 
+GnashPluginScriptObject::marshalRemoveProperty (NPObject *npobj, NPIdentifier 
name)
+{
+//    GnashLogDebug(__PRETTY_FUNCTION__);
+
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;    
+    return gpso->RemoveProperty(name);
+}
+
+bool
+GnashPluginScriptObject::HasProperty(NPIdentifier name)
+{
+//    GnashLogDebug(__PRETTY_FUNCTION__);
+
+#if 0
+    printf("Checking for Property \"");
+    if (NPN_IdentifierIsString(name)) {
+        printf("%s\"...", NPN_UTF8FromIdentifier(name));
+    } else {
+        printf("%d\"...", NPN_IntFromIdentifier(name));
+    }
+#endif
+    
+    std::map<NPIdentifier, NPVariant *>::iterator it;
+    it = _properties.find(name);
+    if (it != _properties.end()) {
+        // printf(" FOUND\n");
+        return true;
+    }
+    
+    return false;
+};
+
+bool
+GnashPluginScriptObject::GetProperty(NPIdentifier name, NPVariant *result)
+{
+//    GnashLogDebug(__PRETTY_FUNCTION__);
+
+    printf("Getting Property \"");
+    if (NPN_IdentifierIsString(name)) {
+        printf("%s\"...", NPN_UTF8FromIdentifier(name));
+    } else {
+        printf("%d\"...", NPN_IntFromIdentifier(name));
+    }
+    
+    std::map<NPIdentifier, NPVariant *>::iterator it;
+    it = _properties.find(name);
+    if (it != _properties.end()) {
+        printf(" FOUND = ");
+        // We have to copy the data we hold internally into the result
+        // data object, rather than just resetting the result point to
+        // our internal copy, which doesn't work.
+        NPVariant *value = it->second;
+        if (NPVARIANT_IS_DOUBLE(*value)) {
+            double num = NPVARIANT_TO_DOUBLE(*value);
+            printf(" %g\n", num);
+            DOUBLE_TO_NPVARIANT(num, *result);
+        } else if (NPVARIANT_IS_STRING(*value)) {
+            printf(" %s\n", NPVARIANT_TO_STRING(*value).UTF8Characters);
+            STRINGN_TO_NPVARIANT(NPVARIANT_TO_STRING(*value).UTF8Characters,
+                                 NPVARIANT_TO_STRING(*value).UTF8Length,
+                                 *result);
+        } else if (NPVARIANT_IS_BOOLEAN(*value)) {
+            printf(" %d\n", NPVARIANT_TO_BOOLEAN(*value));
+            BOOLEAN_TO_NPVARIANT(NPVARIANT_TO_BOOLEAN(*value), *result);
+        } else if (NPVARIANT_IS_INT32(*value)) {
+            printf(" %d\n", NPVARIANT_TO_INT32(*value));
+            INT32_TO_NPVARIANT(NPVARIANT_TO_INT32(*value), *result);
+        } else if (NPVARIANT_IS_NULL(*value)) {
+            printf(" null value\n");
+            NULL_TO_NPVARIANT(*result);
+        } else if (NPVARIANT_IS_VOID(*value)) {
+            printf(" void value\n");
+            VOID_TO_NPVARIANT(*result);
+        } else if (NPVARIANT_IS_OBJECT(*value)) {
+            printf(" object\n");
+            OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(*value), *result);
+        }
+        return true;
+    }
+
+    return false;
+};
+
+bool
+GnashPluginScriptObject::SetProperty(NPIdentifier name, const NPVariant *value)
+{
+    // GnashLogDebug(__PRETTY_FUNCTION__);
+
+    _properties[name] = const_cast<NPVariant *>(value);
+
+    return false;
+}
+
+bool
+GnashPluginScriptObject::RemoveProperty(NPIdentifier name)
+{
+    // GnashLogDebug(__PRETTY_FUNCTION__);
+
+    std::map<NPIdentifier, NPVariant *>::iterator it;
+    it = _properties.find(name);
+    if (it != _properties.end()) {
+        _properties.erase(it);
+        return true;
+    }    
+    
+    return false;
+}
+
+bool
+GnashPluginScriptObject::HasMethod(NPIdentifier name)
+{
+//    GnashLogDebug(__PRETTY_FUNCTION__);
+
+#if 0
+    printf("Checking for Method \"");
+    if (NPN_IdentifierIsString(name)) {
+        printf("%s\"...", NPN_UTF8FromIdentifier(name));
+    } else {
+        printf("%d\"...", NPN_IntFromIdentifier(name));
+    }
+#endif
+
+    std::map<NPIdentifier, NPInvokeFunctionPtr>::iterator it;
+    it = _methods.find(name);
+    if (it != _methods.end()) {
+        // printf(" FOUND\n");
+        return true;
+    }    
+    
+    return false;
+}
+
+bool
+GnashPluginScriptObject::Invoke(NPIdentifier name, const NPVariant *args, 
uint32_t argCount, NPVariant *result)
+{
+//    GnashLogDebug(__PRETTY_FUNCTION__);
+#if 1
+    printf("Invoking Method \"");
+    if (NPN_IdentifierIsString(name)) {
+        printf("%s\"...", NPN_UTF8FromIdentifier(name));
+    } else {
+        printf("%d\"...", NPN_IntFromIdentifier(name));
+    }
+#endif
+
+    std::map<NPIdentifier, NPInvokeFunctionPtr>::iterator it;
+    it = _methods.find(name);
+    if (it != _methods.end()) {
+        printf(" FOUND\n");
+        NPInvokeFunctionPtr func = it->second;
+        return func(NULL, name, args, argCount, result);
+    }    
+
+    return false;
+}
+
+bool
+GnashPluginScriptObject::InvokeDefault(const NPVariant *args, uint32_t 
argCount, NPVariant *result)
+{
+    GnashLogDebug(__PRETTY_FUNCTION__);
+#if 0
+    printf("Invoking Default Method \"");
+    if (NPN_IdentifierIsString(name)) {
+        printf("%s\"...\n", NPN_UTF8FromIdentifier(name));
+    } else {
+        printf("%d\"...\n", NPN_IntFromIdentifier(name));
+    }
+#endif
+
+    return false;
+}
+
+bool
+GnashPluginScriptObject::AddMethod(NPIdentifier name, NPInvokeFunctionPtr func)
+{
+//    GnashLogDebug(__PRETTY_FUNCTION__);
+    
+#if 0
+    printf("Adding Method \"");
+    if (NPN_IdentifierIsString(name)) {
+        printf("%s\"...\n", NPN_UTF8FromIdentifier(name));
+    } else {
+        printf("%d\"...\n", NPN_IntFromIdentifier(name));
+    }
+#endif
+
+    _methods[name] = func;
+    
+    return true;
+}
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:

=== added file 'plugin/npapi/pluginScriptObject.h'
--- a/plugin/npapi/pluginScriptObject.h 1970-01-01 00:00:00 +0000
+++ b/plugin/npapi/pluginScriptObject.h 2010-04-08 22:39:09 +0000
@@ -0,0 +1,109 @@
+// 
+//   Copyright (C) 2010 Free Software Foundation, Inc
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+//
+
+#ifdef HAVE_CONFIG_H
+#include "gnashconfig.h"
+#endif
+
+// Test:
+//     Use browser to open plugin/scriptable-test.html.
+//
+// Notes:
+// 1. In order not to rewrite the whole Plugin, just be _scriptObject 
+//    of nsPluginInstance.
+// 2. GnashPluginScriptObject is the marshal object to response 
+//    JavaScript, no function to gtk-gnash yet.
+// 3. Once gnash::Player support multiple instance, it's possible to 
+//    the bridge between JavaScript and ActionScript.
+//
+// Todo:
+//    Support the methods listed in
+//    
http://www.adobe.com/support/flash/publishexport/scriptingwithflash/scriptingwithflash_03.html
+
+#ifndef GNASH_PLUGIN_SCRIPT_OBJECT_H
+#define GNASH_PLUGIN_SCRIPT_OBJECT_H
+
+#include <map>
+
+#include "npapi.h"
+#include "npruntime.h"
+
+class GnashPluginScriptObject : public NPObject
+{
+public:
+
+    GnashPluginScriptObject();
+    GnashPluginScriptObject(NPP npp);
+    ~GnashPluginScriptObject();
+    
+    static NPClass *marshalGetNPClass();
+
+    // NPObject static Functions. These get used by the browser, which is
+    // why they have to be static.
+    static NPObject *marshalAllocate (NPP npp, NPClass *aClass);
+    static void marshalDeallocate (NPObject *npobj);
+    static void marshalInvalidate (NPObject *npobj);
+    static bool marshalHasMethod (NPObject *npobj, NPIdentifier name);
+    static bool marshalInvoke (NPObject *npobj, NPIdentifier name,
+                               const NPVariant *args, uint32_t argCount,
+                               NPVariant *result);
+    static bool marshalInvokeDefault (NPObject *npobj, const NPVariant *args,
+                                      uint32_t argCount, NPVariant *result);
+    static bool marshalHasProperty (NPObject *npobj, NPIdentifier name);
+    static bool marshalGetProperty (NPObject *npobj, NPIdentifier name,
+                                    NPVariant *result);
+    static bool marshalSetProperty (NPObject *npobj, NPIdentifier name,
+                                    const NPVariant *value);
+    static bool marshalRemoveProperty (NPObject *npobj, NPIdentifier name);
+    
+    static NPClass _npclass;
+    
+protected:
+    bool AddMethod(NPIdentifier name, NPInvokeFunctionPtr func);
+    void AddProperty(const std::string &name, const std::string &str);
+    void AddProperty(const std::string &name, double num);
+    void AddProperty(const std::string &name, int num);
+
+    // Internal functions
+    void Deallocate();
+    void Invalidate();
+    bool HasMethod(NPIdentifier name);
+
+    bool Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, 
NPVariant *result);
+    bool InvokeDefault(const NPVariant *args, uint32_t argCount, NPVariant 
*result);
+    bool HasProperty(NPIdentifier name);
+    bool GetProperty(NPIdentifier name, NPVariant *result);
+    bool SetProperty(NPIdentifier name, const NPVariant *value);
+    bool RemoveProperty(NPIdentifier name);
+    bool Enumerate(NPIdentifier **identifier, uint32_t *count);
+    bool Construct(const NPVariant *args, uint32_t argCount, NPVariant 
*result);
+private:
+    void initializeIdentifiers();
+    // _nppinstance->pdata should be the nsPluginInstance once NPP_New() is 
finished.
+    NPP _nppinstance;
+
+    std::map<NPIdentifier, NPVariant *> _properties;
+    std::map<NPIdentifier,  NPInvokeFunctionPtr> _methods;
+};
+
+#endif /* GNASH_PLUGIN_SCRIPT_OBJECT_H */
+
+// local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:

=== added file 'plugin/npapi/scriptable-test.html'
--- a/plugin/npapi/scriptable-test.html 1970-01-01 00:00:00 +0000
+++ b/plugin/npapi/scriptable-test.html 2010-04-08 22:39:09 +0000
@@ -0,0 +1,107 @@
+<HTML>
+<HEAD>
+<TITLE>Scriptable Plugin Test</TITLE>
+</HEAD>
+<BODY>
+
+<center>
+<h1> Scriptable Plugin </h1>
+</center>
+
+<br><br>
+
+<center>
+
+<embed type="application/x-shockwave-flash" width=1 height=1 hidden="true"><br>
+
+<script>
+var embed = document.embeds[0];
+
+function ShowVersion()
+{
+        document.write("Codebase =  = " + embed.codebase + "<br>");
+        document.write("Classid = " + embed.classid + "<br>");
+        document.write("Pluginspage = " + embed.pluginspage + "<br>");
+        document.write("Src = " + embed.src + "<br>");
+        document.write("BG Color = " + embed.bgcolor + "<br>");
+        document.write("Quality = " + embed.quality + "<br>");
+        document.write("movie = " + embed.movie + "<br>");
+        document.write("onafterupdate = " + embed.onafterupdate + "<br>");
+        document.write("onbeforeupdate = " + embed.onbeforeupdate + "<br>");
+        document.write("onblur = " + embed.onblur + "<br>");
+        document.write("oncellchange = " + embed.oncellchange + "<br>");
+        document.write("onclick = " + embed.onclick + "<br>");
+        document.write("ondblClick = " + embed.ondblClick + "<br>");
+        document.write("ondrag = " + embed.ondrag + "<br>");
+        document.write("ondragend = " + embed.ondragend + "<br>");
+        document.write("ondragenter = " + embed.ondragenter + "<br>");
+        document.write("ondragleave = " + embed.ondragleave + "<br>");
+        document.write("ondragover = " + embed.ondragover + "<br>");
+        document.write("ondrop = " + embed.ondrop + "<br>");
+        document.write("onfinish = " + embed.onfinish + "<br>");
+        document.write("onfocus = " + embed.onfocus + "<br>");
+        document.write("onhelp = " + embed.onhelp + "<br>");
+        document.write("onmousedown = " + embed.onmousedown + "<br>");
+        document.write("onmouseup = " + embed.onmouseup + "<br>");
+        document.write("onmouseover = " + embed.onmouseover + "<br>");
+        document.write("onmousemove = " + embed.onmousemove + "<br>");
+        document.write("onmouseout = " + embed.onmouseout + "<br>");
+        document.write("onkeypress = " + embed.onkeypress + "<br>");
+        document.write("onkeydown = " + embed.onkeydown + "<br>");
+        document.write("onkeyup = " + embed.onkeyup + "<br>");
+        document.write("onload = " + embed.onload + "<br>");
+        document.write("onlosecapture = " + embed.onlosecapture + "<br>");
+        document.write("onpropertychange = " + embed.onpropertychange + 
"<br>");
+        document.write("onreadystatechange = " + embed.onreadystatechange + 
"<br>");
+        document.write("onrowsdelete = " + embed.onrowsdelete + "<br>");
+        document.write("onrowenter = " + embed.onrowenter + "<br>");
+        document.write("onrowexit = " + embed.onrowexit + "<br>");
+        document.write("onrowsinserted = " + embed.onrowsinserted + "<br>");
+        document.write("onstart = " + embed.onstart + "<br>");
+        document.write("onscroll = " + embed.onscroll + "<br>");
+        document.write("onbeforeeditfocus = " + embed.onbeforeeditfocus + 
"<br>");
+        document.write("onactivate = " + embed.onactivate) + "<br>";
+        document.write("onbeforedeactivate = " + embed.onbeforedeactivate + 
"<br>");
+        document.write("ondeactivate = " + embed.ondeactivate + "<br>");
+        document.write("type = " + embed.type + "<br>");
+        document.write("id = " + embed.id + "<br>");
+        document.write("width = " + embed.width + "<br>");
+        document.write("height = " + embed.height + "<br>");
+        document.write("align = " + embed.align + "<br>");
+        document.write("vspace", + embed.vspace + "<br>");
+        document.write("hspace = " + embed.hspace + "<br>");
+        document.write("class = " + embed.class + "<br>");
+        document.write("title = " + embed.title + "<br>");
+       document.write("accesskey = " + embed.accesskey + "<br>");
+       document.write("name = " + embed.name + "<br>");
+        document.write("tabindex = " + embed.tabindex + "<br>");
+        document.write("FlashVars = " + embed.FlashVars + "<br>");
+
+       alert(embed.version);
+}
+
+function ShowFoobar(msg)
+{
+       alert(embed.showFoobar(msg));
+}
+</script>
+
+<br>
+<form name="form1">
+<input type=button value="Show Version" onclick='ShowVersion()'>
+</form>
+<br>
+<form name="form">
+<input type=button value="Show Foobar" onclick='ShowFoobar("barfood")'>
+</form>
+
+</center>
+
+</BODY>
+</HTML>
+
+<!--
+local Variables:
+indent-tabs-mode: nil
+End:
+-->


reply via email to

[Prev in Thread] Current Thread [Next in Thread]