gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r12142: Implement the client side of


From: Rob Savoye
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r12142: Implement the client side of a network interface to Gnash for Scriptable support.
Date: Sat, 10 Apr 2010 12:43:28 -0600
User-agent: Bazaar (2.0.3)

------------------------------------------------------------
revno: 12142 [merge]
committer: Rob Savoye <address@hidden>
branch nick: trunk
timestamp: Sat 2010-04-10 12:43:28 -0600
message:
  Implement the client side of a network interface to Gnash for Scriptable 
support.
added:
  plugin/npapi/README
modified:
  plugin/npapi/plugin.cpp
  plugin/npapi/pluginScriptObject.cpp
  plugin/npapi/pluginScriptObject.h
  plugin/npapi/scriptable-test.html
=== added file 'plugin/npapi/README'
--- a/plugin/npapi/README       1970-01-01 00:00:00 +0000
+++ b/plugin/npapi/README       2010-04-10 18:33:53 +0000
@@ -0,0 +1,156 @@
+  There is a simple, but crude interface between the plugin and Gnash
+running standalone, that supports the ExternalInterface ActionScript
+class. This is currently purely ASCII based, although it wouldn't be
+hard to change to a binary protocol. The bandwidth is minor, and XML
+would be overkill, so for now it's just text keywords, delimited by
+spaces. A CR is used to terminate each message.
+
+SetVariable( Name, Value )
+   Sets the value of the Flash variable specified by Name to
+   Value. The value is everything from the last delimiter to the end
+   of the line.
+   
+   Sends:
+       "Command Name Type value\n",
+               ie... "SetVariable var1 string value1\n"
+   Receives:
+       nothing
+
+GetVariable( Name )
+   Returns the value of the Flash variable specified by Name. Returns
+   null if the variable does not exist.
+
+   Sends:
+       "Command Name\n", ie... "GetVariable var1\n"
+
+   Receives:
+       "Command Name Type value", ie... "GetVariable var1 string value1\n"
+
+PercentLoaded()
+   Returns the percent of the Flash Player movie that has streamed
+   into the browser so far; possible values are from 0 to 100. 
+
+   Sends:
+       "Command\n", ie... "PercentLoaded\n"
+
+   Receives:
+       "Command number\n", ie... "PercentLoaded 23\n"
+
+Zoom( percent )
+   Zooms the view by a relative scale factor specified by percent.
+   Zoom(50) doubles the size of the objects in the view. Zoom(200)
+   reduces the size of objects in the view by one half. Zoom(0) resets
+   the view to 100%.
+
+   Sends:
+       "Command number\n", ie... "Zoom 200\n"
+
+   Receives:
+       nothing
+
+GotoFrame( frameNumber )
+   Activates the frame number specified by frameNumber in the current
+   movie. If the data for a requested frame is not yet available, the
+   player goes to the last frame available and stops, causing
+   unexpected results during playback. Use the PercentLoaded() method
+   to determine if enough of the movie is available to execute the
+   GotoFrame() method.
+
+   Sends:
+       "Command number\n", ie... "GotoFrame 77\n"
+
+   Receives:
+       nothing
+
+IsPlaying()
+   Returns true if the movie is currently playing.
+
+   Sends:
+       "Command\n", ie... "IsPlaying\n"
+
+   Receives:
+       "Command Flag", ie... "IsPlaying true\n"
+
+Play();
+  Starts the movie playing.
+
+   Sends:
+       "Command\n", ie... "Play\n"
+
+   Receives:
+       nothing
+
+Rewind();
+   Goes to the first frame.
+
+   Sends:
+       "Command\n", ie... "Rewind\n"
+
+   Receives:
+       nothing
+
+SetZoomRect ( left, top, right, bottom )
+   Zooms in on a rectangular area of the movie. The units of the
+   coordinates are in twips (1440 units per inch). To calculate a
+   rectangle in Flash, set the ruler units to Points and multiply the
+   coordinates by 20 to get twips.
+
+   Sends:
+       "Command left top right bottom\n", ie... "SetZoomRect 0 0 10 10\n"
+
+   Receives:
+       nothing
+
+
+LoadMovie( layer, url )
+   Loads the movie identified by url to the layer specified by
+   layerNumber.  The argument type is integer for layer and
+   string for url.
+ 
+   Sends:
+       "Command Layer Url\n", ie... "LoadMovie 1 /foo.swf\n"
+
+   Receives:
+       nothing
+
+ StopPlay()
+   Stops playing the movie.
+
+   Sends:
+       "Command StopPlay\n", ie... "StopPlay\n"
+
+   Receives:
+       nothing
+
+TotalFrames()
+   Returns the total number of frames in the movie.
+
+   Sends:
+       "Command TotalFrames\n", ie... "TotalFrames\n"
+
+   Receives:
+       "Command Num\n", ie... "TotalFrames 1234\n"
+
+Pan ( x, y, mode ) 
+   Pans a zoomed-in movie to the coordinates specified by x and y. Use
+   mode to specify whether the values for x and y are pixels or a
+   percent of the window. When mode is either pixels or percent of the
+   window.
+
+   Sends:
+       "Command Pan x y mode\n", ie... "Pan 10 10 pixels\n"
+
+   Receives:
+       nothing
+
+---------------
+
+  Many of the methods don't supposedly have a return value, so for now
+commands are sent blindy, and the only ones that expect a response at
+all are few. To be more tightly coupled, (I figured loosely coupled is
+ok for now) every command sent should get an boolean back stating
+whether the command worked correctly on the GNash side of things.
+
+  For methods that don't appear to return anything, the result
+NPVariant data is set to true or false just in case.
+

=== modified file 'plugin/npapi/plugin.cpp'
--- a/plugin/npapi/plugin.cpp   2010-04-09 16:48:11 +0000
+++ b/plugin/npapi/plugin.cpp   2010-04-10 18:43:28 +0000
@@ -23,7 +23,16 @@
 
 #include <cstdlib> // getenv
 #include <stdlib.h> // putenv
-#include <sys/socket.h> // shutdown
+#include <sys/types.h>
+#if defined(HAVE_WINSOCK_H) && !defined(__OS2__)
+# include <winsock2.h>
+# include <windows.h>
+#else
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+# include <sys/socket.h> // shutdown
+#endif
 
 #define MIME_TYPES_HANDLED  "application/x-shockwave-flash"
 // The name must be this value to get flash movies that check the
@@ -58,9 +67,15 @@
 //  1: fatal errors (errors preventing the plugin from working as it should)
 //  2: informational messages
 //
-#define GNASH_PLUGIN_DEBUG 2
+#define GNASH_PLUGIN_DEBUG 1
 //#define WRITE_FILE
 
+// Defining this flag disables the pipe to the standalone player, as well
+// as prevents the standalone Gnash player from being exec'd. Instead it
+// makes a network connection to localhost:1111 so the developer can use
+// Netcat (nc) to send and receive messages to test the interface.
+#undef NETTEST
+
 #include "plugin.h" 
 #include "GnashSystemIOHeaders.h"
 #include "StringPredicates.h"
@@ -333,6 +348,8 @@
     _filefd(-1),
     _name()
 {
+    // GnashLogDebug(__PRETTY_FUNCTION__);
+
     for (size_t i=0, n=data->argc; i<n; ++i) {
         std::string name, val;
         gnash::StringNoCaseEqual noCaseCompare;
@@ -355,6 +372,36 @@
 #ifdef ENABLE_SCRIPTABLE
     _scriptObject = NPNFuncs.createobject(_instance, 
GnashPluginScriptObject::marshalGetNPClass());
 #endif
+#if defined(ENABLE_SCRIPTABLE) && defined(NETTEST)
+    // This is a network testing node switch. This is only used for testing the
+    // interface between the player and the plugin.
+    struct sockaddr_in  sock_in;
+    memset(&sock_in, 0, sizeof(struct sockaddr_in));
+    sock_in.sin_family = AF_INET;
+    sock_in.sin_port = ntohs(1111);
+    const struct hostent *hent = ::gethostbyname("localhost");
+    if (hent > 0) {
+        ::memcpy(&sock_in.sin_addr, hent->h_addr, hent->h_length);
+    }
+    struct protoent     *proto;
+    proto = ::getprotobyname("TCP");
+    int sockfd = ::socket(PF_INET, SOCK_STREAM, proto->p_proto);
+    if (sockfd > 0) {
+        int ret = ::connect(sockfd, 
+                            reinterpret_cast<struct sockaddr *>(&sock_in),
+                            sizeof(sock_in));
+        if (ret == 0) {
+            GnashLogDebug("Connected to debug server");
+            _controlfd = sockfd;
+            GnashPluginScriptObject *gpso = (GnashPluginScriptObject 
*)_scriptObject;
+            gpso->setControlFD(_controlfd);
+        } else {
+            GnashLogError("Couldn't connect to debug server");
+        }
+    }
+#endif
+    
+    return;
 }
 
 gboolean
@@ -499,14 +546,22 @@
 
     _window = reinterpret_cast<Window> (aWindow->window);
 
+#ifdef ENABLE_SCRIPTABLE
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)_scriptObject;
+//    printf("FIXME: the control FD is #%d\n", _controlfd);
+    gpso->setControlFD(_controlfd);
+#endif
+
+    // When testing the interface to the plugin, don't start the player
+    // as a debug client "nc -l 1111" is used instead.
+#ifndef NETTEST
     if (!_childpid && !_swf_url.empty()) {
         startProc();
     }
-
+#endif
     return NPERR_NO_ERROR;
 }
 
-
 NPError
 nsPluginInstance::GetValue(NPPVariable aVariable, void *aValue)
 {
@@ -523,14 +578,13 @@
     return NS_PluginGetValue(aVariable, aValue);
 }
 
-#if 0
+#if 1
 // 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)
 {
@@ -562,10 +616,10 @@
     }
     _swf_url = stream->url;
 
-#if 0
+#if 1
     // FIXME: debugging crap for now call javascript
     NPN_PluginThreadAsyncCall(_instance, myfunc, NULL);
-//    printf("FIXME: %s", getEmbedURL());
+    // printf("FIXME: %s", getEmbedURL());
 #endif
     
     
@@ -1041,35 +1095,36 @@
     }
 
     _controlfd = p2c_controlpipe[1];
-
+    
     /*
     Setup the command line for starting Gnash
     */
 
-    std::vector<std::string> arg_vec = getCmdLine(c2p_pipe[1], 
p2c_controlpipe[0]);
+    std::vector<std::string> arg_vec = getCmdLine(c2p_pipe[1],
+                                                  p2c_controlpipe[0]);
     if (arg_vec.empty()) {
         GnashLogError("Failed to obtain command line parameters.");
         return;
     }
-
+    
     std::vector<const char*> args;
-
+    
     std::transform(arg_vec.begin(), arg_vec.end(), std::back_inserter(args),
                    std::mem_fun_ref(&std::string::c_str));
     args.push_back(0);
-
+    
     /*
       Argument List prepared, now fork(), close file descriptors and execv()
-     */
-
+    */
+    
     _childpid = fork();
-
+    
     // If the fork failed, childpid is -1. So print out an error message.
     if (_childpid == -1) {
         GnashLogError("ERROR: dup2() failed: " + std::string(strerror(errno)));
         return;
     }
-
+    
     // If we are the parent and fork() worked, childpid is a positive integer.
     if (_childpid > 0) {
         
@@ -1077,33 +1132,33 @@
         ret = close (p2c_pipe[0]);
         if (ret == -1) {
             GnashLogError("ERROR: p2c_pipe[0] close() failed: " +
-                     std::string(strerror(errno)));
+                          std::string(strerror(errno)));
         }
-
+        
         // we want to read from c2p pipe, so close write-fd1
         ret = close (c2p_pipe[1]);
         if (ret == -1) {
             GnashLogError("ERROR: c2p_pipe[1] close() failed: " + 
-                     std::string(strerror(errno)));
+                          std::string(strerror(errno)));
         }
-
+        
         ret = close (p2c_controlpipe[0]); // close read descriptor
-    
+        
 #if GNASH_PLUGIN_DEBUG > 1
         std::cout << "Forked successfully, child process PID is " 
-                                << _childpid
-                                << std::endl;
+                  << _childpid
+                  << std::endl;
 #endif
-
+        
         GIOChannel* ichan = g_io_channel_unix_new(c2p_pipe[0]);
         g_io_channel_set_close_on_unref(ichan, true);
         _ichanWatchId = g_io_add_watch(ichan, 
-                (GIOCondition)(G_IO_IN|G_IO_HUP), 
-                (GIOFunc)handlePlayerRequestsWrapper, this);
+                                       (GIOCondition)(G_IO_IN|G_IO_HUP), 
+                                       (GIOFunc)handlePlayerRequestsWrapper, 
this);
         g_io_channel_unref(ichan);
         return;
     }
-
+    
     // This is the child scope.
     
     // FF3 uses jemalloc and it has problems after the fork(), do NOT

=== modified file 'plugin/npapi/pluginScriptObject.cpp'
--- a/plugin/npapi/pluginScriptObject.cpp       2010-04-09 16:50:12 +0000
+++ b/plugin/npapi/pluginScriptObject.cpp       2010-04-10 18:33:53 +0000
@@ -25,7 +25,20 @@
 #include <sstream>
 #include <map>
 #include <string>
-
+#include <fcntl.h>
+#include <cstring>
+#include <cstdlib>
+#if defined(HAVE_WINSOCK_H) && !defined(__OS2__)
+# include <winsock2.h>
+# include <windows.h>
+# include <sys/stat.h>
+# include <io.h>
+# include <ws2tcpip.h>
+#else
+# include <sys/ioctl.h>
+# include <unistd.h>
+# include <sys/select.h>
+#endif
 #include "npapi.h"
 #include "npruntime.h"
 #include "plugin.h" 
@@ -54,34 +67,10 @@
     GnashPluginScriptObject::marshalConstruct
 };
 
-// FIXME: The Flash variables should be changed in the standalone player,
-// but for now we're going to cheat and store them locally.
-std::map<std::string, NPVariant *> _variables;
+static int controlfd = -1;
 
 #if 0
 
-// From 
http://www.adobe.com/support/flash/publishexport/scriptingwithflash/scriptingwithflash_03.html
-// var movie = window.document.movie
-
-#define NUM_METHOD_IDENTIFIERS       13
-static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
-// Standard Methods
-static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
-   "SetVariable",
-   "GetVariable",
-   "GotoFrame",
-   "IsPlaying",
-   "LoadMovie",
-   "Pan",
-   "PercentLoaded",
-   "Play",
-   "Rewind",
-   "SetZoomRect",
-   "StopPlay",
-   "Zoom",
-   "TotalFrames"
-};
-
 // 
http://www.adobe.com/support/flash/publishexport/scriptingwithflash/scriptingwithflash_04.html
 // Tell Target Methods. Use TGetProperty, TGetPropertyAsNumber, TSetProperty
 TCallLabel
@@ -134,9 +123,20 @@
 }
 
 // Callbacks for the default methods
+
+// As these callbacks use a generalized typedef for the signature, often some
+// of the parameters can be ignored. These are commented out to elimnate the
+// volumnes of bogus warnings about not using them in the method.
+
+// SetVariable( Name, Value )
+// Sends:
+//      "Command Name Type value\n",
+//             ie... "SetVariable var1 string value1\n"
+// Receives:
+//      nothing
 bool
 SetVariableCallback (NPObject *npobj, NPIdentifier /* name */, const NPVariant 
*args,
-          uint32_t argCount, NPVariant */* result */)
+          uint32_t argCount, NPVariant *result)
 {   
     GnashLogDebug(__PRETTY_FUNCTION__);
 
@@ -148,143 +148,527 @@
         NPVariant *value = const_cast<NPVariant *>(&args[1]);
         // printf("Setting Variable \"%s\"\n", varname.c_str());
         gpso->SetVariable(varname, value);
-        return true;
-    }
-    
-    return false;
-}
-
-bool
-GetVariableCallback (NPObject */* npobj */, NPIdentifier /* name */, const 
NPVariant */*args */,
-          uint32_t /* argCount */, NPVariant *result)
-{   
-    GnashLogDebug(__PRETTY_FUNCTION__);
-    
-    DOUBLE_TO_NPVARIANT(122333.4444, *result);
-    
-    return true;
-}
-
-bool
-GotoFrame (NPObject */* npobj */, NPIdentifier /* name */, const NPVariant 
*/*args */,
-          uint32_t /* argCount */, NPVariant *result)
-{   
-    GnashLogDebug(__PRETTY_FUNCTION__);
-    
-    DOUBLE_TO_NPVARIANT(122333.4444, *result);
-    
-    return true;
-}
-
-bool
-IsPlaying (NPObject */* npobj */, NPIdentifier /* name */, const NPVariant 
*/*args */,
-          uint32_t /* argCount */, NPVariant *result)
-{   
-    GnashLogDebug(__PRETTY_FUNCTION__);
-    
-    DOUBLE_TO_NPVARIANT(122333.4444, *result);
-    
-    return true;
-}
-
-bool
-LoadMovie (NPObject */* npobj */, NPIdentifier /* name */, const NPVariant 
*/*args */,
-          uint32_t /* argCount */, NPVariant *result)
-{   
-    GnashLogDebug(__PRETTY_FUNCTION__);
-    
-    DOUBLE_TO_NPVARIANT(122333.4444, *result);
-    
-    return true;
-}
-
-bool
-Pan (NPObject */* npobj */, NPIdentifier /* name */, const NPVariant */*args 
*/,
-          uint32_t /* argCount */, NPVariant *result)
-{   
-    GnashLogDebug(__PRETTY_FUNCTION__);
-    
-    DOUBLE_TO_NPVARIANT(122333.4444, *result);
-    
-    return true;
-}
-
-bool
-PercentLoaded (NPObject */* npobj */, NPIdentifier /* name */, const NPVariant 
*/*args */,
-          uint32_t /* argCount */, NPVariant *result)
-{   
-    GnashLogDebug(__PRETTY_FUNCTION__);
-    
-    DOUBLE_TO_NPVARIANT(122333.4444, *result);
-    
-    return true;
-}
-
-bool
-Play (NPObject */* npobj */, NPIdentifier /* name */, const NPVariant */*args 
*/,
-          uint32_t /* argCount */, NPVariant *result)
-{   
-    GnashLogDebug(__PRETTY_FUNCTION__);
-    
-    DOUBLE_TO_NPVARIANT(122333.4444, *result);
-    
-    return true;
-}
-
-bool
-Rewind (NPObject */* npobj */, NPIdentifier /* name */, const NPVariant 
*/*args */,
-          uint32_t /* argCount */, NPVariant *result)
-{   
-    GnashLogDebug(__PRETTY_FUNCTION__);
-    
-    DOUBLE_TO_NPVARIANT(122333.4444, *result);
-    
-    return true;
-}
-
-bool
-SetZoomRect (NPObject */* npobj */, NPIdentifier /* name */, const NPVariant 
*/*args */,
-          uint32_t /* argCount */, NPVariant *result)
-{   
-    GnashLogDebug(__PRETTY_FUNCTION__);
-    
-    DOUBLE_TO_NPVARIANT(122333.4444, *result);
-    
-    return true;
-}
-
-bool
-StopPlay (NPObject */* npobj */, NPIdentifier /* name */, const NPVariant 
*/*args */,
-          uint32_t /* argCount */, NPVariant *result)
-{   
-    GnashLogDebug(__PRETTY_FUNCTION__);
-    
-    DOUBLE_TO_NPVARIANT(122333.4444, *result);
-    
-    return true;
-}
-
-bool
-Zoom (NPObject */* npobj */, NPIdentifier /* name */, const NPVariant */* args 
*/,
-          uint32_t /* argCount */, NPVariant *result)
-{   
-    GnashLogDebug(__PRETTY_FUNCTION__);
-    
-    DOUBLE_TO_NPVARIANT(122333.4444, *result);
-    
-    return true;
-}
-
-bool
-TotalFrames (NPObject */* npobj */, NPIdentifier /* name */, const NPVariant 
*/*args */,
-          uint32_t /* argCount */, NPVariant *result)
-{   
-    GnashLogDebug(__PRETTY_FUNCTION__);
-    
-    DOUBLE_TO_NPVARIANT(122333.4444, *result);
-    
-    return true;
-}
+        BOOLEAN_TO_NPVARIANT(true, *result);
+        return true;
+    }
+    
+    BOOLEAN_TO_NPVARIANT(false, *result);
+    return false;
+}
+
+// GetVariable( Name )
+//    Sends:
+//     "Command Name\n", ie... "GetVariable var1\n"
+//
+//    Receives:
+//     "Command Name Type value", ie... "GetVariable var1 string value1\n"
+bool
+GetVariableCallback (NPObject *npobj, NPIdentifier /* name */,
+                     const NPVariant *args,
+                     uint32_t argCount, NPVariant *result)
+{   
+    GnashLogDebug(__PRETTY_FUNCTION__);
+    
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+    std::string varname;
+    // This method only takes one argument
+    if (argCount == 1) {
+        varname = NPVARIANT_TO_STRING(args[0]).UTF8Characters;
+        NPVariant *value = gpso->GetVariable(varname);
+        if (value == 0) {
+            NPVARIANT_IS_VOID(*value);
+        } else {
+            if (NPVARIANT_IS_DOUBLE(*value)) {
+                double num = NPVARIANT_TO_DOUBLE(*value);
+                DOUBLE_TO_NPVARIANT(num, *result);
+            } else if (NPVARIANT_IS_STRING(*value)) {
+                
STRINGN_TO_NPVARIANT(NPVARIANT_TO_STRING(*value).UTF8Characters,
+                                     NPVARIANT_TO_STRING(*value).UTF8Length,
+                                     *result);
+            } else if (NPVARIANT_IS_BOOLEAN(*value)) {
+                BOOLEAN_TO_NPVARIANT(NPVARIANT_TO_BOOLEAN(*value), *result);
+            } else if (NPVARIANT_IS_INT32(*value)) {
+                INT32_TO_NPVARIANT(NPVARIANT_TO_INT32(*value), *result);
+            } else if (NPVARIANT_IS_NULL(*value)) {
+                NULL_TO_NPVARIANT(*result);
+            } else if (NPVARIANT_IS_VOID(*value)) {
+            VOID_TO_NPVARIANT(*result);
+            } else if (NPVARIANT_IS_OBJECT(*value)) {
+                OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(*value), *result);
+            }
+            return true;
+        }
+    }
+    
+    return false;
+}
+
+// GotoFrame( frameNumber )
+//    Sends:
+//     "Command number\n", ie... "GotoFrame 77\n"
+//
+//    Receives:
+//     nothing
+bool
+GotoFrame (NPObject *npobj, NPIdentifier /* name */, const NPVariant *args,
+          uint32_t argCount, NPVariant *result)
+{   
+    GnashLogDebug(__PRETTY_FUNCTION__);
+
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+    std::string varname;
+    if (argCount == 1) {
+        int value = NPVARIANT_TO_INT32(args[0]);
+        std::stringstream ss;
+        ss << "GotoFrame " << value << std::endl;
+        // Write the message to the Control FD.
+        size_t ret = gpso->writePlayer(gpso->getControlFD(), ss.str());
+        // Unless we wrote the same amount of data as the message contained,
+        // something went wrong.
+        if (ret != ss.str().size()) {
+            GnashLogError("Couldn't goto the specified frame, network 
problems.");
+            return false;
+        }        
+        // gpso->GotoFrame(value);
+        BOOLEAN_TO_NPVARIANT(true, *result);
+        return true;
+    }
+    
+    BOOLEAN_TO_NPVARIANT(false, *result);
+    return false;
+}
+
+// IsPlaying()
+//    Sends:
+//     "Command\n", ie... "IsPlaying\n"
+
+//    Receives:
+//     "Command Flag", ie... "IsPlaying true\n"
+bool
+IsPlaying (NPObject *npobj, NPIdentifier /* name */, const NPVariant */*args 
*/,
+          uint32_t argCount, NPVariant *result)
+{   
+    GnashLogDebug(__PRETTY_FUNCTION__);
+    
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+    if (argCount == 0) {
+        std::stringstream ss;
+        ss << "IsPlaying" << std::endl;
+        // Write the message to the Control FD.
+        size_t ret = gpso->writePlayer(gpso->getControlFD(), ss.str());
+        // Unless we wrote the same amount of data as the message contained,
+        // something went wrong.
+        if (ret != ss.str().size()) {
+            GnashLogError("Couldn't check if the movie is playing, network 
problems.");
+            BOOLEAN_TO_NPVARIANT(false, *result);
+            return false;
+        }        
+        const char *data = 0;
+        char *ptr = 0;
+        ret = gpso->readPlayer(controlfd, &data, 0);
+        if (ret == 0) {
+            BOOLEAN_TO_NPVARIANT(false, *result);
+            return false;
+        }
+        ptr = const_cast<char *>(data);
+        if (strncmp(ptr, "IsPlaying ", 10) != 0) {
+            printf("Illegal response! %s\n", ptr);
+            BOOLEAN_TO_NPVARIANT(false, *result);
+            return false;
+        } else {
+            // A legit response has CR on the end already
+            printf("Legit response: %s", ptr);
+        }    
+        ptr += 10;
+        bool flag = false;
+        if (strncmp(ptr, "true", 4) == 0) {
+            flag = true;
+        } else if (strncmp(ptr, "false", 5) == 0) {
+            flag = false;
+        }
+        BOOLEAN_TO_NPVARIANT(flag, *result);
+        // gpso->IsPlaying(value);
+        return true;
+    }
+    
+    BOOLEAN_TO_NPVARIANT(false, *result);
+    return false;
+}
+
+// LoadMovie( Layer, Url )
+//    Sends:
+//     "Command Layer Url\n", ie... "LoadMovie 1 /foo.swf\n"
+//
+//    Receives:
+//     nothing
+bool
+LoadMovie (NPObject *npobj, NPIdentifier /* name */, const NPVariant *args,
+          uint32_t argCount, NPVariant *result)
+{   
+    GnashLogDebug(__PRETTY_FUNCTION__);
+
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+    if (argCount == 2) {
+        std::stringstream ss;
+        int layer = NPVARIANT_TO_INT32(args[0]);
+        std::string url = NPVARIANT_TO_STRING(args[1]).UTF8Characters;
+        ss << "LoadMovie " << layer << " " << url << std::endl;
+        // Write the message to the Control FD.
+        size_t ret = gpso->writePlayer(gpso->getControlFD(), ss.str());
+        // Unless we wrote the same amount of data as the message contained,
+        // something went wrong.
+        if (ret != ss.str().size()) {
+            GnashLogError("Couldn't load the movie, network problems.");
+            return false;
+        }        
+        // gpso->LoadMovie();
+        BOOLEAN_TO_NPVARIANT(true, *result);
+        return true;
+    }
+    
+    BOOLEAN_TO_NPVARIANT(false, *result);
+    return false;
+}
+
+// Pan ( x, y, mode ) 
+//    Sends:
+//     "Command Pan x y mode\n", ie... "Pan 10 10 pixels\n"
+//
+//    Receives:
+//     nothing
+bool
+Pan (NPObject *npobj, NPIdentifier /* name */, const NPVariant *args,
+          uint32_t argCount, NPVariant *result)
+{   
+    GnashLogDebug(__PRETTY_FUNCTION__);
+    
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+    if (argCount == 3) {
+        std::stringstream ss;
+        NPVariant *value = const_cast<NPVariant *>(&args[0]);
+        int x = NPVARIANT_TO_INT32(*value);
+        value = const_cast<NPVariant *>(&args[1]);
+        int y = NPVARIANT_TO_INT32(*value);
+        value = const_cast<NPVariant *>(&args[2]);
+        int mode = NPVARIANT_TO_INT32(*value);
+        ss << "Pan " << x << y;
+        if (mode) {
+            ss << " pixels";
+        } else {
+            ss << " percent";
+        }
+        ss << std::endl;
+        // Write the message to the Control FD.
+        size_t ret = gpso->writePlayer(gpso->getControlFD(), ss.str());
+        // Unless we wrote the same amount of data as the message contained,
+        // something went wrong.
+        if (ret != ss.str().size()) {
+            GnashLogError("Couldn't pan the movie, network problems.");
+            return false;
+        }        
+        BOOLEAN_TO_NPVARIANT(true, *result);
+        return true;
+    }
+    
+    BOOLEAN_TO_NPVARIANT(false, *result);
+    return false;
+}
+
+// PercentLoaded()
+//    Sends:
+//     "Command\n", ie... "PercentLoaded\n"
+//
+//    Receives:
+//     "Command number\n", ie... "PercentLoaded 23\n"
+bool
+PercentLoaded (NPObject *npobj, NPIdentifier /* name */, const NPVariant 
*/*args */,
+          uint32_t argCount, NPVariant *result)
+{   
+    GnashLogDebug(__PRETTY_FUNCTION__);
+    
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+    if (argCount == 0) {
+        std::stringstream ss;
+        ss << "PercentLoaded" << std::endl;
+        // Write the message to the Control FD.
+        size_t ret = gpso->writePlayer(gpso->getControlFD(), ss.str());
+        // Unless we wrote the same amount of data as the message contained,
+        // something went wrong.
+        if (ret != ss.str().size()) {
+            GnashLogError("Couldn't check percent loaded, network problems.");
+            BOOLEAN_TO_NPVARIANT(false, *result);
+            return false;
+        }        
+        const char *data = 0;
+        char *ptr = 0;
+        ret = gpso->readPlayer(controlfd, &data, 0);
+        if (ret == 0) {
+            BOOLEAN_TO_NPVARIANT(false, *result);
+            return false;
+        }
+        ptr = const_cast<char *>(data);
+        if (strncmp(ptr, "PercentLoaded ", 15) != 0) {
+            printf("Illegal response! %s\n", ptr);
+            BOOLEAN_TO_NPVARIANT(false, *result);
+            return false;
+        } else {
+            // A legit response has CR on the end already
+            printf("Legit response: %s", ptr);
+        }    
+        ptr += 15;
+        int percent = strtol(ptr, NULL, 0);
+        if ((percent >= 0) && (percent <= 100)) {
+            INT32_TO_NPVARIANT(percent, *result);
+        } else {
+            INT32_TO_NPVARIANT(-1, *result);
+        }
+        return true;
+    }
+    
+    BOOLEAN_TO_NPVARIANT(false, *result);
+    return false;
+}
+
+// Play();
+//    Sends:
+//     "Command\n", ie... "Play\n"
+//
+//    Receives:
+//     nothing
+bool
+Play (NPObject *npobj, NPIdentifier /* name */, const NPVariant */*args */,
+          uint32_t argCount, NPVariant *result)
+{   
+    GnashLogDebug(__PRETTY_FUNCTION__);
+
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+    if (argCount == 0) {
+        std::stringstream ss;
+        ss << "Play" << std::endl;
+        // Write the message to the Control FD.
+        size_t ret = gpso->writePlayer(gpso->getControlFD(), ss.str());
+        // Unless we wrote the same amount of data as the message contained,
+        // something went wrong.
+        if (ret != ss.str().size()) {
+            GnashLogError("Couldn't play movie, network problems.");
+            return false;
+        }        
+        // gpso->IsPlaying(value);
+        BOOLEAN_TO_NPVARIANT(true, *result);
+        return true;
+    }
+    
+    BOOLEAN_TO_NPVARIANT(false, *result);
+    return false;
+}
+
+// Rewind();
+//    Sends:
+//     "Command\n", ie... "Rewind\n"
+//
+//    Receives:
+//     nothing
+bool
+Rewind (NPObject *npobj, NPIdentifier /* name */, const NPVariant */*args */,
+          uint32_t argCount, NPVariant *result)
+{   
+    GnashLogDebug(__PRETTY_FUNCTION__);
+
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+    if (argCount == 0) {
+        std::stringstream ss;
+        ss << "Rewind" << std::endl;
+        // Write the message to the Control FD.
+        size_t ret = gpso->writePlayer(gpso->getControlFD(), ss.str());
+        // Unless we wrote the same amount of data as the message contained,
+        // something went wrong.
+        if (ret != ss.str().size()) {
+            GnashLogError("Couldn't rewind movie, network problems.");
+            return false;
+        }        
+        // gpso->Rewind(value);
+        BOOLEAN_TO_NPVARIANT(true, *result);
+        return true;
+    }
+    
+    BOOLEAN_TO_NPVARIANT(false, *result);
+    return false;
+}
+
+// SetZoomRect ( left, top, right, bottom )
+//    Sends:
+//     "Command left top right bottom\n", ie... "SetZoomRect 0 0 10 10\n"
+//
+//    Receives:
+//     nothing
+bool
+SetZoomRect (NPObject *npobj, NPIdentifier /* name */, const NPVariant *args,
+          uint32_t argCount, NPVariant *result)
+{   
+    GnashLogDebug(__PRETTY_FUNCTION__);
+    
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+    if (argCount == 4) {
+        std::stringstream ss;
+        NPVariant *value = const_cast<NPVariant *>(&args[0]);
+        int left = NPVARIANT_TO_INT32(*value);
+        value = const_cast<NPVariant *>(&args[1]);
+        int top = NPVARIANT_TO_INT32(*value);
+        value = const_cast<NPVariant *>(&args[2]);
+        int right = NPVARIANT_TO_INT32(*value);
+        value = const_cast<NPVariant *>(&args[3]);
+        int bottom = NPVARIANT_TO_INT32(*value);
+        ss << "SetZoomRect " << left << " " << top << " ";
+        ss << right << " " << bottom << std::endl;
+        // Write the message to the Control FD.
+        size_t ret = gpso->writePlayer(gpso->getControlFD(), ss.str());
+        // Unless we wrote the same amount of data as the message contained,
+        // something went wrong.
+        if (ret != ss.str().size()) {
+            GnashLogError("Couldn't Set the Zoom Rect the movie, network 
problems.");
+            return false;
+        }        
+        BOOLEAN_TO_NPVARIANT(true, *result);
+        return true;
+    }
+    
+    BOOLEAN_TO_NPVARIANT(false, *result);
+    return false;
+}
+
+// StopPlay()
+//    Sends:
+//     "Command StopPlay\n", ie... "StopPlay\n"
+
+//    Receives:
+//     nothing
+bool
+StopPlay (NPObject *npobj, NPIdentifier /* name */, const NPVariant */*args */,
+          uint32_t argCount, NPVariant *result)
+{   
+    GnashLogDebug(__PRETTY_FUNCTION__);
+    
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+    if (argCount == 0) {
+        std::stringstream ss;
+        ss << "StopPlay" << std::endl;
+        // Write the message to the Control FD.
+        size_t ret = gpso->writePlayer(gpso->getControlFD(), ss.str());
+        // Unless we wrote the same amount of data as the message contained,
+        // something went wrong.
+        if (ret != ss.str().size()) {
+            GnashLogError("Couldn't stop-play movie, network problems.");
+            return false;
+        }        
+        // gpso->IsPlaying(value);
+        BOOLEAN_TO_NPVARIANT(true, *result);
+        return true;
+    }
+    
+    BOOLEAN_TO_NPVARIANT(false, *result);
+    return false;
+}
+
+// Zoom( percent )
+//    Sends:
+//     "Command number\n", ie... "Zoom 200\n"
+//
+//    Receives:
+//     nothing
+bool
+Zoom (NPObject *npobj, NPIdentifier /* name */, const NPVariant *args,
+          uint32_t argCount, NPVariant *result)
+{   
+    GnashLogDebug(__PRETTY_FUNCTION__);
+
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+    if (argCount == 1) {
+        std::stringstream ss;
+        NPVariant *value = const_cast<NPVariant *>(&args[1]);
+        int zoom = NPVARIANT_TO_INT32(*value);
+        ss << "Zoom " << zoom << std::endl;
+        // Write the message to the Control FD.
+        size_t ret = gpso->writePlayer(gpso->getControlFD(), ss.str());
+        // Unless we wrote the same amount of data as the message contained,
+        // something went wrong.
+        if (ret != ss.str().size()) {
+            GnashLogError("Couldn't zoom movie, network problems.");
+            return false;
+        }        
+        BOOLEAN_TO_NPVARIANT(true, *result);
+        return true;
+    }
+    
+    BOOLEAN_TO_NPVARIANT(false, *result);
+    return false;
+}
+
+// TotalFrames()
+//    Sends:
+//     "Command TotalFrames\n", ie... "TotalFrames\n"
+//
+//    Receives:
+//     "Command Num\n", ie... "TotalFrames 1234\n"
+bool
+TotalFrames (NPObject *npobj, NPIdentifier /* name */, const NPVariant */*args 
*/,
+          uint32_t argCount, NPVariant *result)
+{   
+    GnashLogDebug(__PRETTY_FUNCTION__);
+    
+    GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+    if (argCount == 0) {
+        std::stringstream ss;
+        ss << "TotalFrames" << std::endl;
+        // Write the message to the Control FD.
+        size_t ret = gpso->writePlayer(gpso->getControlFD(), ss.str());
+        // Unless we wrote the same amount of data as the message contained,
+        // something went wrong.
+        if (ret != ss.str().size()) {
+            GnashLogError("Couldn't check percent loaded, network problems.");
+            BOOLEAN_TO_NPVARIANT(false, *result);
+            return false;
+        }        
+        const char *data = 0;
+        char *ptr = 0;
+        ret = gpso->readPlayer(controlfd, &data, 0);
+        if (ret == 0) {
+            BOOLEAN_TO_NPVARIANT(false, *result);
+            return false;
+        }
+        ptr = const_cast<char *>(data);
+        if (strncmp(ptr, "TotalFrames ", 13) != 0) {
+            printf("Illegal response! %s\n", ptr);
+            BOOLEAN_TO_NPVARIANT(false, *result);
+            return false;
+        } else {
+            // A legit response has CR on the end already
+            printf("Legit response: %s", ptr);
+        }    
+        ptr += 13;
+        int frames = strtol(ptr, NULL, 0);
+        INT32_TO_NPVARIANT(frames, *result);
+        return true;
+    }
+    
+    BOOLEAN_TO_NPVARIANT(false, *result);
+    return false;
+}
+
+//
+// The methods for GnashPluginScriptObject start here.
+//
 
 void
 GnashPluginScriptObject::AddProperty(const std::string &name,
@@ -295,6 +679,7 @@
     int length = str.size();;
     char *bar = new char[length+1];
     std::copy(str.begin(), str.end(), bar);
+    bar[length] = 0;  // terminate the new string or bad things happen
     STRINGN_TO_NPVARIANT(bar, length, *value);
     SetProperty(id, value);
 }
@@ -666,19 +1051,19 @@
                                  NPVARIANT_TO_STRING(*value).UTF8Length,
                                  *result);
         } else if (NPVARIANT_IS_BOOLEAN(*value)) {
-            printf(" %d\n", NPVARIANT_TO_BOOLEAN(*value));
+            printf(" %d", 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));
+            printf(" %d", NPVARIANT_TO_INT32(*value));
             INT32_TO_NPVARIANT(NPVARIANT_TO_INT32(*value), *result);
         } else if (NPVARIANT_IS_NULL(*value)) {
-            printf(" null value\n");
+            printf(" null value");
             NULL_TO_NPVARIANT(*result);
         } else if (NPVARIANT_IS_VOID(*value)) {
-            printf(" void value\n");
+            printf(" void value");
             VOID_TO_NPVARIANT(*result);
         } else if (NPVARIANT_IS_OBJECT(*value)) {
-            printf(" object\n");
+            printf(" object");
             OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(*value), *result);
         }
         printf("\n");
@@ -815,32 +1200,235 @@
     return true;
 }
 
-void
+// SetVariable sends a message to the player that looks like this:
+// "Command Name Type value\n", ie... "SetVariable var1 string value1\n"
+bool
 GnashPluginScriptObject::SetVariable(const std::string &name,
                                      NPVariant *value)
 {
     GnashLogDebug(__PRETTY_FUNCTION__);
+
+    // Build the command message
     printf("Set Variable \"%s\" to ", name.c_str());
-    
-#if 1
-    if (NPVARIANT_IS_STRING(*value)) {
+    std::stringstream ss;
+    ss << "SetVariable " << name;
+    if (NPVARIANT_IS_DOUBLE(*value)) {
+        ss << " double " << NPVARIANT_TO_DOUBLE(*value);
+    } else if (NPVARIANT_IS_STRING(*value)) {
         std::string varname = NPVARIANT_TO_STRING(*value).UTF8Characters;
-        printf("%s\n", varname.c_str());
-    } else if (NPVARIANT_IS_DOUBLE(*value)) {
-        printf("%g\n", NPVARIANT_TO_DOUBLE(*value));
-    }
-#endif
-
-    _variables[name] = value;
+        ss << " string " << varname;
+    } else if (NPVARIANT_IS_BOOLEAN(*value)) {
+        ss << " boolean " << NPVARIANT_TO_BOOLEAN(*value);
+    } else if (NPVARIANT_IS_INT32(*value)) {
+        ss << " int32 " << NPVARIANT_TO_INT32(*value);
+    } else if (NPVARIANT_IS_NULL(*value)) {
+        ss << " null";
+    } else if (NPVARIANT_IS_VOID(*value)) {
+        ss << " void";
+    } else if (NPVARIANT_IS_OBJECT(*value)) {
+        ss << " object";         // FIXME: add the object data
+    }
+
+    // Add the CR, so we know where the message ends when parsing.
+    ss << std::endl;
+    // Write the message to the Control FD.
+    size_t ret = writePlayer(controlfd, ss.str());
+    // Unless we wrote the same amount of data as the message contained,
+    // something went wrong.
+    if (ret != ss.str().size()) {
+        GnashLogError("Couldn't set the variable, network problems.");
+        return false;
+    }
+
+    return true;
 }
 
+// GetVariable sends a message to the player that looks like this:
+// "Command Name\n", ie... "GetVariable var1\n". Then it waits
+// for the response with the type and value.
 NPVariant *
 GnashPluginScriptObject::GetVariable(const std::string &name)
 {
     GnashLogDebug(__PRETTY_FUNCTION__);
-
-    return _variables[name];
-}
+    printf("Get Variable \"%s\" is ", name.c_str());
+
+    NPVariant *value = 0;
+    std::stringstream ss;
+    
+    ss << "GetVariable " << name << std::endl;
+    writePlayer(controlfd, ss.str());
+
+    // Have the read function allocate the memory
+    const char *data = 0;
+    char *ptr = 0;
+    int ret = readPlayer(controlfd, &data, 0);
+    if (ret == 0) {
+        return value;
+    }
+
+    ptr = const_cast<char *>(data);
+    value = new NPVariant;
+
+    // Make sure this mesasge is our response, whnich it should be,
+    // but you never know...
+    if (strncmp(ptr, "GetVariable ", 12) != 0) {
+        printf("Illegal response! %s\n", ptr);
+        return value;
+    } else {
+        // A legit response has CR on the end already
+        printf("Legit response: %s", ptr);
+    }    
+    ptr += 12;
+
+#if 0
+    if (strncmp(ptr, name.c_str(), name.size()) == 0) {
+        printf("Mismatched variable name! %s\n", ptr);
+        return value;
+    } else {
+        printf("Variable names matched: %s\n", ptr);
+    }
+#endif
+    ptr += name.size() + 1;     // don't forget to skip the space
+    
+    if (strncmp(ptr, "double ", 7) == 0) {
+        double num = strtod(ptr, NULL);
+        ptr += 7;
+        printf("\tdouble %s = %g\n", name.c_str(), num);
+        DOUBLE_TO_NPVARIANT(num, *value);
+    } else if (strncmp(ptr, "string ", 7) == 0) {
+        ptr += 7;
+        std::string str(ptr);
+        printf("\tstring %s = %s\n", name.c_str(), str.c_str());
+    } else if (strncmp(ptr, "boolean ", 8) == 0) {
+        ptr += 8;
+        bool flag = strtol(ptr, NULL, 0);
+        printf("\tboolean %s = %d\n", name.c_str(), flag);
+        BOOLEAN_TO_NPVARIANT(flag, *value);
+    } else if (strncmp(ptr, "int32 ", 6) == 0) {
+        ptr += 6;
+        int num = strtol(ptr, NULL, 0);
+        printf("\tint32 %s = %d\n", name.c_str(), num);
+        INT32_TO_NPVARIANT(num, *value);
+    } else if (strncmp(ptr, "null ", 5) == 0) {
+        ptr += 5;
+        printf("\t%s = null\n", name.c_str());
+        NULL_TO_NPVARIANT(*value);
+    } else if (strncmp(ptr, "void ", 5) == 0) {
+        ptr += 5;
+        printf("\t%s = void\n", name.c_str());
+        VOID_TO_NPVARIANT(*value);
+    } else if (strncmp(ptr, "object ", 7) == 0) {
+        ptr += 7;
+        printf("\tFIXME: %s = object\n", name.c_str());
+        // OBJECT_TO_NPVARIANT(num, *value);
+    }
+
+    ss << std::endl;
+
+    // free the memory used for the data, as it was allocated in readPlayer().
+    delete[](data);
+    
+    return value;
+}
+
+void
+GnashPluginScriptObject::setControlFD(int x)
+{
+    GnashLogDebug(__PRETTY_FUNCTION__);
+    controlfd = x;
+}
+
+int
+GnashPluginScriptObject::getControlFD()
+{
+    GnashLogDebug(__PRETTY_FUNCTION__);
+
+    return controlfd;
+};
+
+
+// Write to the standalone player over the control socket
+int
+GnashPluginScriptObject::writePlayer(int fd, const std::string &data)
+{
+    GnashLogDebug(__PRETTY_FUNCTION__);
+    return writePlayer(fd, data.c_str(), data.size());
+}
+
+int
+GnashPluginScriptObject::writePlayer(int fd, const char *data, size_t length)
+{
+//    GnashLogDebug(__PRETTY_FUNCTION__);
+    
+    if (controlfd > 0) {
+        return ::write(fd, data, length);
+    }
+    
+    return 0;
+}
+
+// Read the standalone player over the control socket
+int
+GnashPluginScriptObject::readPlayer(int /* fd */, const std::string &/* data 
*/)
+{
+//    GnashLogDebug(__PRETTY_FUNCTION__);
+
+//    return readPlayer(fd, data.c_str(), data.size());
+
+    return -1;
+}
+
+int
+GnashPluginScriptObject::readPlayer(int fd, const char **data, size_t length)
+{
+//    GnashLogDebug(__PRETTY_FUNCTION__);
+
+    if (fd > 0) {
+        // Wait for some data from the player
+        int bytes = 0;
+        fd_set fdset;
+        FD_ZERO(&fdset);
+        FD_SET(fd, &fdset);
+        struct timeval tval;
+        tval.tv_sec = 10;
+        tval.tv_usec = 0;
+        printf("Waiting for data... ");
+        if (select(fd+1, &fdset, NULL, NULL, &tval)) {
+            // printf("There is data in the network\n");
+#ifndef _WIN32
+            ioctl(fd, FIONREAD, &bytes);
+#else
+            ioctlSocket(fd, FIONREAD, &bytes);
+#endif
+        // } else {
+        //     printf("There is no data in thhe network\n");
+        }
+        
+
+        printf("There are %d bytes in the network buffer\n", bytes);
+        // No data yet
+        if (bytes == 0) {
+            return 0;
+        }
+
+        char *buf = 0;
+        if (*data == 0) {
+            // Since we know how bytes are in the network buffer, allocate
+            // some memory to read the data.
+            buf = new char[bytes+1];
+            // terminate incase we want to treat the data like a string.
+            buf[bytes] = 0;
+            length = bytes;
+        }
+        int ret = ::read(fd, buf, bytes);
+        if (ret == bytes) {
+            *data = buf;
+        }
+        return ret;
+    }
+    
+    return 0;
+}   
 
 // local Variables:
 // mode: C++

=== modified file 'plugin/npapi/pluginScriptObject.h'
--- a/plugin/npapi/pluginScriptObject.h 2010-04-09 16:50:12 +0000
+++ b/plugin/npapi/pluginScriptObject.h 2010-04-10 16:43:47 +0000
@@ -78,8 +78,27 @@
     
     static NPClass _npclass;
 
-    void SetVariable(const std::string &name, NPVariant *value);
+    /// Scripting API support. This is where all the protocol support
+    /// lives.
+
+    //  The ControlFD is the file descriptor for the socket connection
+    // to the standalone player.
+    void setControlFD(int x);
+    int getControlFD();
+
+    /// Set a variable in the standalone player
+    bool SetVariable(const std::string &name, NPVariant *value);
+    
+    /// Get the value of a variable from the standalone player
     NPVariant *GetVariable(const std::string &name);
+
+    // Write to the standalone player over the control socket
+    int writePlayer(int fd, const char *data, size_t length);
+    int writePlayer(int fd, const std::string &data);
+    
+    // Read the standalone player over the control socket
+    int readPlayer(int fd, const char **data, size_t length);
+    int readPlayer(int fd, const std::string &data);
     
 protected:
     bool AddMethod(NPIdentifier name, NPInvokeFunctionPtr func);
@@ -102,9 +121,10 @@
     bool Construct(const NPVariant *data, 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;
 };

=== modified file 'plugin/npapi/scriptable-test.html'
--- a/plugin/npapi/scriptable-test.html 2010-04-09 16:48:41 +0000
+++ b/plugin/npapi/scriptable-test.html 2010-04-10 18:33:53 +0000
@@ -1,83 +1,173 @@
-<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);
+<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 FlashSetVariable(name, value)
+{
+          embed.SetVariable(name, value);
+//          alert("FlashSetVariable");
+}
+
+function FlashGetVariable(name)
+{
+          var value = embed.GetVariable(name);
+//          document.write("Got Variable = " + value + "<br>");          
+          alert(value);
+}
+
+function FlashGotoFrame(num)
+{
+          embed.GotoFrame(num);
+//          document.write("GotoFrame<br>");
+//          alert(value);
+}
+
+function FlashIsPlaying()
+{
+          var value = embed.IsPlaying();
+//          document.write("IsPlaying() = " + value + "<br>");          
+          alert(value);
+}
+
+function FlashLoadMovie(layer, name)
+{
+          embed.LoadMovie(layer, name);
+//          document.write("LoadMovie()<br>");
+//          alert("FlashLoadMovie");
+}
+
+function FlashPan(x, y, mode)
+{
+          embed.Pan(x, y, mode);
+//          document.write("Pan()<br>");
+//          alert("FlashPan");
+}
+
+function FlashPercentLoaded()
+{
+          var value = embed.PercentLoaded();
+//          document.write("PercentLoaded() = " + value + "<br>");          
+          alert(value);
+}
+
+function FlashPlay()
+{
+//          embed.Play();
+//          document.write("Play()<br>");
+        alert("FlashPlay");
+}
+
+function FlashRewind()
+{
+//          embed.Rewind();
+//          document.write("Rewind()<br>");
+        alert("FlashRewind");
+}
+
+function FlashSetZoomRect(left, top, right, bottom)
+{
+          embed.SetZoomRect(left, top, right, bottom);
+//          document.write("SetZoomRect()<br>");
+//        alert("FlashSetZoomRect");
+}
+
+function FlashStopPlay()
+{
+          embed.StopPlay();
+//          document.write("StopPlay()<br>");
+//        alert("FlashStopPlay");
+}
+
+function FlashZoom(zoom)
+{
+          embed.Zoom(zoom);
+//          document.write("Zoom()<br>");
+//        alert("FlashZoom");
+}
+
+function FlashTotalFrames()
+{
+          var value = embed.TotalFrames();
+//          document.write("TotalFrames() = " + value + "<br>");          
+          alert(value);
 }
 
 function ShowFoobar(msg)
@@ -95,14 +185,101 @@
 <input type=button value="Show Version" onclick='ShowVersion()'>
 </form>
 <br>
-<form name="form">
+
+<form name="form2">
 <input type=button value="Show Foobar" onclick='ShowFoobar("barfood")'>
 </form>
 
 </center>
 
-</BODY>
-</HTML>
+<div id="main">
+<table>
+  <tr><td>
+      <form name="form3">
+        <input type=button value="SetVariable" 
onclick='FlashSetVariable("var1", "value1")'>
+      </form>
+    </td>
+
+    <td>
+      <form name="form4">
+        <input type=button value="GetVariable" 
onclick='FlashGetVariable("var1")'>
+      </form>
+    </td>
+
+    <td>
+      <form name="form5">
+        <input type=button value="GotoFrame" onclick='FlashGotoFrame(123)'>
+      </form>
+    </td>
+
+    <td>
+      <form name="form6">
+        <input type=button value="IsPlaying" onclick='FlashIsPlaying()'>
+      </form>
+    </td>
+
+    <td>
+      <form name="form7">
+        <input type=button value="LoadMovie" onclick='FlashLoadMovie(2, 
"bogus")'>
+      </form>
+    </td>
+
+    <td>
+      <form name="form8">
+        <input type=button value="Pan" onclick='FlashPan(1, 2, 0)'>
+      </form>
+      
+    </td>
+
+    <td>
+      <form name="form9">
+        <input type=button value="PercentLoaded" 
onclick='FlashPercentLoaded()'>
+      </form>
+    </td>
+
+  </tr><tr>
+
+    <td>
+      <form name="form10">
+        <input type=button value="Play" onclick='FlashPlay()'>
+      </form>
+    </td>
+
+    <td>
+      <form name="form11">
+        <input type=button value="Rewind" onclick='FlashRewind()'>
+      </form>
+    </td>
+
+    <td>      
+      <form name="form12">
+        <input type=button value="SetZoomRect" onclick='FlashSetZoomRect(1, 2, 
3, 4)'>
+      </form>
+
+    </td>
+
+    <td>
+      <form name="form13">
+        <input type=button value="StopPlay" onclick='FlashStopPlay()'>
+      </form>
+    </td>
+
+    <td>
+      <form name="form14">
+        <input type=button value="Zoom" onclick='FlashZoom(12)'>
+      </form>      
+    </td>
+
+    <td>
+      <form name="form15">
+        <input type=button value="TotalFrames" onclick='FlashTotalFrames()'>
+      </form>
+    </td></tr>
+</table>
+</div>
+
+</body>
+</html>
 
 <!--
 local Variables:


reply via email to

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