Selaa lähdekoodia

urlnotify etc

David Rose 16 vuotta sitten
vanhempi
sitoutus
16dd9cb633

+ 1 - 0
direct/src/plugin/.gitignore

@@ -0,0 +1 @@
+/p3d_plugin_config.h

+ 2 - 0
direct/src/plugin/Sources.pp

@@ -77,3 +77,5 @@
      load_plugin.cxx load_plugin.h
 
 #end static_lib_target
+
+#include $[THISDIRPREFIX]p3d_plugin_config.h.pp

+ 2 - 5
direct/src/plugin/load_plugin.cxx

@@ -13,6 +13,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "load_plugin.h"
+#include "p3d_plugin_config.h"
 
 #ifndef _WIN32
 #include <dlfcn.h>
@@ -146,11 +147,7 @@ load_plugin(const string &p3d_plugin_filename) {
   // Successfully loaded.
   plugin_loaded = true;
 
-#ifdef _WIN32
-  string logfilename = "c:/cygwin/home/drose/t0.log";
-#else
-  string logfilename = "/Users/drose/t0.log";
-#endif
+  string logfilename = P3D_PLUGIN_LOGFILE2;
 
   if (!P3D_initialize(P3D_API_VERSION, logfilename.c_str())) {
     // Oops, failure to initialize.

+ 12 - 0
direct/src/plugin/p3dInstanceManager.I

@@ -48,6 +48,18 @@ get_download_url() const {
   return _download_url;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: P3DInstanceManager::get_platform
+//       Access: Public
+//  Description: Returns the string that corresponds to the platform
+//               on which we are running.  This string will be used to
+//               determine the appropriate packages to download.
+////////////////////////////////////////////////////////////////////
+inline const string &P3DInstanceManager::
+get_platform() const {
+  return _platform;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DInstanceManager::get_command_instance
 //       Access: Public

+ 7 - 9
direct/src/plugin/p3dInstanceManager.cxx

@@ -16,6 +16,7 @@
 #include "p3dInstance.h"
 #include "p3dSession.h"
 #include "p3dPackage.h"
+#include "p3d_plugin_config.h"
 
 #ifdef _WIN32
 #include <shlobj.h>
@@ -91,15 +92,11 @@ P3DInstanceManager::
 bool P3DInstanceManager::
 initialize() {
   _root_dir = find_root_dir();
-  nout << "_root_dir = " << _root_dir << "\n";
+  _download_url = P3D_PLUGIN_DOWNLOAD;
+  _platform = P3D_PLUGIN_PLATFORM;
 
-#ifdef _WIN32
-  //  _download_url = "http://10.196.143.118/~drose/p3d/";
-  _download_url = "http://www.ddrose.com/~drose/p3d/";
-
-#else
-  _download_url = "http://www.ddrose.com/~drose/p3d/";
-#endif
+  nout << "_root_dir = " << _root_dir << ", download = " 
+       << _download_url << "\n";
 
   if (_root_dir.empty()) {
     nout << "Could not find root directory.\n";
@@ -240,7 +237,8 @@ wait_request() {
 ////////////////////////////////////////////////////////////////////
 P3DPackage *P3DInstanceManager::
 get_package(const string &package_name, const string &package_version, 
-            const string &package_platform, const string &package_display_name) {
+            const string &package_display_name) {
+  string package_platform = get_platform();
   string key = package_name + "_" + package_version + "_" + package_platform;
   Packages::iterator pi = _packages.find(key);
   if (pi != _packages.end()) {

+ 2 - 1
direct/src/plugin/p3dInstanceManager.h

@@ -41,6 +41,7 @@ public:
 
   inline const string &get_root_dir() const;
   inline const string &get_download_url() const;
+  inline const string &get_platform() const;
 
   P3DInstance *
   create_instance(P3D_request_ready_func *func,
@@ -55,7 +56,6 @@ public:
 
   P3DPackage *get_package(const string &package_name, 
                           const string &package_version,
-                          const string &package_platform,
                           const string &package_display_name);
 
   inline P3DInstance *get_command_instance() const;
@@ -77,6 +77,7 @@ private:
   bool _is_initialized;
   string _root_dir;
   string _download_url;
+  string _platform;
 
   P3DInstance *_command_instance;
 

+ 7 - 11
direct/src/plugin/p3dSession.cxx

@@ -17,6 +17,7 @@
 #include "p3dInstanceManager.h"
 #include "p3dProgressWindow.h"
 #include "p3dWinProgressWindow.h"
+#include "p3d_plugin_config.h"
 
 #ifndef _WIN32
 #include <fcntl.h>
@@ -50,13 +51,7 @@ P3DSession(P3DInstance *inst) {
 
   P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
 
-#ifdef _WIN32
-  string platform = "win32";
-#else
-  string platform = "osx.i386";
-#endif
-
-  _panda3d = inst_mgr->get_package("panda3d", "dev", platform, "Panda3D");
+  _panda3d = inst_mgr->get_package("panda3d", "dev", "Panda3D");
   _panda3d_callback = NULL;
   _python_root_dir = _panda3d->get_package_dir();
 
@@ -241,12 +236,13 @@ send_command(TiXmlDocument *command) {
 ////////////////////////////////////////////////////////////////////
 void P3DSession::
 start_p3dpython() {
+  string p3dpython = P3D_PLUGIN_P3DPYTHON;
+  if (p3dpython.empty()) {
+    p3dpython = _python_root_dir + "/p3dpython";
 #ifdef _WIN32
-  string p3dpython = "c:/cygwin/home/drose/player/direct/built/bin/p3dpython.exe";
-  //string p3dpython = _python_root_dir + "/p3dpython.exe";
-#else
-  string p3dpython = "/Users/drose/player/direct/built/bin/p3dpython";
+    p3dpython += ".exe"
 #endif
+  }
 
   // Populate the new process' environment.
   string env;

+ 33 - 0
direct/src/plugin/p3d_plugin_config.h.pp

@@ -0,0 +1,33 @@
+// This file is read and processed by ppremake to generate
+// p3d_plugin_config.h.
+
+#output p3d_plugin_config.h notouch
+/* p3d_plugin_config.h.  Generated automatically by $[PPREMAKE] $[PPREMAKE_VERSION] from $[notdir $[THISFILENAME]]. */
+/********************************** DO NOT EDIT ****************************/
+
+/* The URL that is the root of the download server that this plugin
+   should contact.  The nppanda3d.dll file should be found at this
+   location; as well as the contents.xml file that defines where the
+   various Panda3D packages will be found. */
+#$[]define P3D_PLUGIN_DOWNLOAD "$[P3D_PLUGIN_DOWNLOAD]$[if $[notdir $[P3D_PLUGIN_DOWNLOAD]],/]"
+
+/* The filename(s) to generate output to when the plugin is running.
+   For debugging purposes only. */
+#$[]define P3D_PLUGIN_LOGFILE1 "$[osfilename $[P3D_PLUGIN_LOGFILE1]]"
+#$[]define P3D_PLUGIN_LOGFILE2 "$[osfilename $[P3D_PLUGIN_LOGFILE2]]"
+
+/* Temporary: the location at which p3dpython.exe can be found.  Empty
+   string for the default. */
+#$[]define P3D_PLUGIN_P3DPYTHON "$[osfilename $[P3D_PLUGIN_P3DPYTHON]]"
+
+/* The string that corresponds to this particular platform. */
+#if $[not $[P3D_PLUGIN_PLATFORM]]
+  #if $[WINDOWS_PLATFORM]
+    #define P3D_PLUGIN_PLATFORM win32
+  #else
+    #define P3D_PLUGIN_PLATFORM osx.i386
+  #endif
+#endif
+#$[]define P3D_PLUGIN_PLATFORM "$[P3D_PLUGIN_PLATFORM]"
+
+#end p3d_plugin_config.h

+ 2 - 0
direct/src/plugin_npapi/Sources.pp

@@ -17,10 +17,12 @@
 
   #define SOURCES \
     nppanda3d_common.h \
+    ppDownloadRequest.h ppDownloadRequest.I \
     ppInstance.h ppInstance.I \
     startup.h
 
   #define INCLUDED_SOURCES \
+    ppDownloadRequest.cxx \
     ppInstance.cxx \
     startup.cxx
  

+ 1 - 0
direct/src/plugin_npapi/nppanda3d_composite1.cxx

@@ -1,3 +1,4 @@
+#include "ppDownloadRequest.cxx"
 #include "ppInstance.cxx"
 #include "startup.cxx"
 

+ 163 - 6
direct/src/plugin_npapi/ppInstance.cxx

@@ -13,6 +13,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "ppInstance.h"
+#include "p3d_plugin_config.h"
 
 ////////////////////////////////////////////////////////////////////
 //     Function: PPInstance::Constructor
@@ -28,6 +29,9 @@ PPInstance(NPMIMEType pluginType, NPP instance, uint16 mode,
   logfile << "constructing " << this << "\n" << flush;
   _inst = NULL;
 
+  _npp_instance = instance;
+  _npp_mode = mode;
+
   // Copy the tokens and save them within this object.
   _tokens.reserve(argc);
   for (int i = 0; i < argc; ++i) {
@@ -39,8 +43,18 @@ PPInstance(NPMIMEType pluginType, NPP instance, uint16 mode,
     _tokens.push_back(token);
   }
 
-  _npp_mode = mode;
+  _started_instance_data = false;
+  _got_instance_data = false;
   _got_window = false;
+
+  // Start the plugin DLL downloading.
+  string url = P3D_PLUGIN_DOWNLOAD;
+  url += P3D_PLUGIN_PLATFORM;
+  url += "/";
+  url += get_plugin_basename();
+
+  PPDownloadRequest *req = new PPDownloadRequest(PPDownloadRequest::RT_core_dll);
+  browser->geturlnotify(_npp_instance, url.c_str(), NULL, req);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -85,28 +99,171 @@ set_window(NPWindow *window) {
   _window = *window;
   _got_window = true;
   
-  if (_inst != NULL) {
+  if (_inst == NULL) {
+    create_instance();
+  } else {
     send_window();
   }
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: PPInstance::new_stream
+//       Access: Public
+//  Description: Receives notification of a new stream object, e.g. a
+//               url request.
+////////////////////////////////////////////////////////////////////
+NPError PPInstance::
+new_stream(NPMIMEType type, NPStream *stream, bool seekable, uint16 *stype) {
+  if (stream->notifyData == NULL) {
+    // This is an unsolicited stream.  Assume the first unsolicited
+    // stream we receive is the instance data; any other unsolicited
+    // stream is an error.
+    if (!_started_instance_data) {
+      stream->notifyData = new PPDownloadRequest(PPDownloadRequest::RT_instance_data);
+      *stype = NP_ASFILEONLY;
+      return NPERR_NO_ERROR;
+    }
+
+    // This is an unexpected unsolicited stream.  (Firefox seems to
+    // give us the instance data twice for some reason.)
+    return NPERR_GENERIC_ERROR;
+  }
+
+  PPDownloadRequest *req = (PPDownloadRequest *)(stream->notifyData);
+  switch (req->_rtype) {
+  case PPDownloadRequest::RT_core_dll:
+    // This is the core API DLL (or dylib or whatever).  We want to
+    // download this to file so we can run it directly.
+    *stype = NP_ASFILEONLY;
+    return NPERR_NO_ERROR;
+
+  default:
+    // Don't know what this is.
+    logfile << "Unexpected request " << (int)req->_rtype << "\n";
+  }
+
+  return NPERR_GENERIC_ERROR;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPInstance::destroy_stream
+//       Access: Public
+//  Description: Called by the browser to mark the end of a stream;
+//               the file has either been successfully downloaded or
+//               failed.
+////////////////////////////////////////////////////////////////////
+NPError PPInstance::
+destroy_stream(NPStream *stream, NPReason reason) {
+  return NPERR_NO_ERROR;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPInstance::url_notify
+//       Access: Public
+//  Description: Called by the browser to announce the end of a
+//               stream.  This normally follows destroy_stream(),
+//               unless the stream was never created in the first
+//               place.
+////////////////////////////////////////////////////////////////////
+void PPInstance::
+url_notify(const char *url, NPReason reason, void *notifyData) {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PPInstance::stream_as_file
+//       Access: Public
+//  Description: Called by the browser to report the filename that
+//               contains the fully-downloaded stream contents.
+////////////////////////////////////////////////////////////////////
+void PPInstance::
+stream_as_file(NPStream *stream, const char *fname) {
+  if (stream->notifyData == NULL) {
+    logfile << "Unexpected stream_as_file on " << stream->url << "\n";
+    return;
+  }
+
+  string filename = fname;
+#ifdef __APPLE__
+  // Safari seems to want to report the filename in the old-style form
+  // "Macintosh HD:blah:blah:blah" instead of the new-style form
+  // "/blah/blah/blah".  How annoying.
+  if (filename.substr(0, 13) == "Macintosh HD:") {
+    string fname2;
+    for (size_t p = 12; p < filename.size(); ++p) {
+      if (filename[p] == ':') {
+        fname2 += '/';
+      } else {
+        fname2 += filename[p];
+      }
+    }
+    filename = fname2;
+    logfile << "converted filename to " << filename << "\n";
+  }
+
+#endif  // __APPLE__
+
+  PPDownloadRequest *req = (PPDownloadRequest *)(stream->notifyData);
+  switch (req->_rtype) {
+  case PPDownloadRequest::RT_core_dll:
+    // This is the core API DLL (or dylib or whatever).  Now that
+    // we've downloaded it, we can load it.
+    logfile << "got plugin\n";
+    if (!load_plugin(filename)) {
+      logfile << "Unable to launch core API.\n";
+    }
+    break;
+
+  case PPDownloadRequest::RT_instance_data:
+    // This is the instance data, e.g. the p3d filename.  Now we can
+    // launch the instance.
+    _got_instance_data = true;
+    _p3d_filename = filename;
+    create_instance();
+    break;
+
+  default:
+    // Don't know what this is.
+    logfile << "Unexpected stream_as_file, type " << (int)req->_rtype << "\n";
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: PPInstance::create_instance
 //       Access: Private
-//  Description: Actually creates the internal P3D_instance object.
+//  Description: Actually creates the internal P3D_instance object, if
+//               possible and needed.
 ////////////////////////////////////////////////////////////////////
 void PPInstance::
 create_instance() {
-  assert(_inst == NULL);
+  if (_inst != NULL) {
+    // Already created.
+    return;
+  }
+
+  if (!is_plugin_loaded()) {
+    // Plugin is not loaded yet.
+    return;
+  }
+
+  if (!_got_instance_data) {
+    // No instance data yet.
+    return;
+  }
+
+  if (!_got_window) {
+    // No window yet.
+    return;
+  }
+
   const P3D_token *tokens = NULL;
   if (!_tokens.empty()) {
     tokens = &_tokens[0];
   }
 
   _inst = P3D_create_instance
-    (NULL, NULL, tokens, _tokens.size());
+    (NULL, _p3d_filename.c_str(), tokens, _tokens.size());
 
-  if (_inst != NULL && _got_window) {
+  if (_inst != NULL) {
     send_window();
   }
 }

+ 11 - 1
direct/src/plugin_npapi/ppInstance.h

@@ -33,15 +33,25 @@ public:
   ~PPInstance();
 
   void set_window(NPWindow *window);
+  NPError new_stream(NPMIMEType type, NPStream *stream, 
+                     bool seekable, uint16 *stype);
+  NPError destroy_stream(NPStream *stream, NPReason reason);
+  void url_notify(const char *url, NPReason reason, void *notifyData);
+  void stream_as_file(NPStream *stream, const char *fname);
 
 private:
   void create_instance();
   void send_window();
 
 private:
+  NPP _npp_instance;
+  unsigned int _npp_mode;
   typedef vector<P3D_token> Tokens;
   Tokens _tokens;
-  unsigned int _npp_mode;
+
+  bool _started_instance_data;
+  bool _got_instance_data;
+  string _p3d_filename;
 
   bool _got_window;
   NPWindow _window;

+ 42 - 20
direct/src/plugin_npapi/startup.cxx

@@ -13,6 +13,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include "startup.h"
+#include "p3d_plugin_config.h"
 
 #ifdef _WIN32
 #include <malloc.h>
@@ -26,11 +27,7 @@ static bool logfile_is_open = false;
 static void
 open_logfile() {
   if (!logfile_is_open) {
-#ifdef _WIN32
-    logfile.open("c:/cygwin/home/drose/t.log");
-#else
-    logfile.open("/Users/drose/t.log");
-#endif
+    logfile.open(P3D_PLUGIN_LOGFILE1);
     logfile_is_open = true;
   }
 }
@@ -62,6 +59,7 @@ NP_Initialize(NPNetscapeFuncs *browserFuncs,
 
   logfile << "browserFuncs = " << browserFuncs << "\n" << flush;
 
+  /*
 #ifdef _WIN32
   string plugin_location = "c:/cygwin/home/drose/player/direct/built/lib/p3d_plugin.dll";
 #else
@@ -72,6 +70,7 @@ NP_Initialize(NPNetscapeFuncs *browserFuncs,
     logfile << "couldn't load plugin\n" << flush;
     return NPERR_INVALID_PLUGIN_ERROR;
   }
+  */
 
   return NPERR_NO_ERROR;
 }
@@ -147,8 +146,9 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode,
 ////////////////////////////////////////////////////////////////////
 NPError
 NPP_Destroy(NPP instance, NPSavedData **save) {
-  logfile << "destroy instance\n" << flush;
-  (*save) = NULL;
+  logfile << "destroy instance " << instance << "\n";
+  logfile << "save = " << (void *)save << "\n" << flush;
+  //  (*save) = NULL;
   delete (PPInstance *)(instance->pdata);
   instance->pdata = NULL;
 
@@ -172,6 +172,8 @@ NPP_SetWindow(NPP instance, NPWindow *window) {
   PPInstance *inst = (PPInstance *)(instance->pdata);
   assert(inst != NULL);
   inst->set_window(window);
+
+  return NPERR_NO_ERROR;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -186,18 +188,13 @@ NPError
 NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, 
               NPBool seekable, uint16 *stype) {
   logfile << "NewStream " << type << ", " << stream->url 
-          << ", " << stream->end << "\n" << flush;
+          << ", " << stream->end 
+          << ", notifyData = " << stream->notifyData
+          << "\n" << flush;
   PPInstance *inst = (PPInstance *)(instance->pdata);
   assert(inst != NULL);
 
-  //inst->new_stream(type, stream, seekable, stype);
-
-  *stype = NP_ASFILEONLY;
-
-  if (strcmp(type, "application/x-panda3d") == 0) {
-    return NPERR_NO_ERROR;
-  }
-  return NPERR_GENERIC_ERROR;
+  return inst->new_stream(type, stream, seekable, stype);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -207,8 +204,16 @@ NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream,
 ////////////////////////////////////////////////////////////////////
 NPError 
 NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason) {
-  logfile << "DestroyStream\n" << flush;
-  return NPERR_NO_ERROR;
+  logfile << "DestroyStream " << stream->url 
+          << ", " << stream->end 
+          << ", notifyData = " << stream->notifyData
+          << ", reason = " << reason
+          << "\n" << flush;
+
+  PPInstance *inst = (PPInstance *)(instance->pdata);
+  assert(inst != NULL);
+
+  return inst->destroy_stream(stream, reason);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -244,7 +249,16 @@ NPP_Write(NPP instance, NPStream *stream, int32 offset,
 ////////////////////////////////////////////////////////////////////
 void
 NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname) {
-  logfile << "StreamAsFile: " << fname << "\n" << flush;
+  logfile << "StreamAsFile " << stream->url 
+          << ", " << stream->end 
+          << ", notifyData = " << stream->notifyData
+          << "\n" << flush;
+  logfile << "filename: " << fname << "\n" << flush;
+
+  PPInstance *inst = (PPInstance *)(instance->pdata);
+  assert(inst != NULL);
+
+  inst->stream_as_file(stream, fname);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -276,7 +290,15 @@ NPP_HandleEvent(NPP instance, void *event) {
 void
 NPP_URLNotify(NPP instance, const char *url,
               NPReason reason, void *notifyData) {
-  logfile << "URLNotify: " << url << "\n";
+  logfile << "URLNotify: " << url 
+          << ", notifyData = " << notifyData
+          << ", reason = " << reason
+          << "\n" << flush;
+
+  PPInstance *inst = (PPInstance *)(instance->pdata);
+  assert(inst != NULL);
+
+  inst->url_notify(url, reason, notifyData);
 }
 
 ////////////////////////////////////////////////////////////////////