From 6c73c0d08df2103f524f6da0d11023773c0d7147 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 23 Jun 2009 02:11:32 +0000 Subject: [PATCH] more work --- direct/src/plugin/Sources.pp | 1 + direct/src/plugin/load_plugin_src.cxx | 2 +- direct/src/plugin/make_contents.py | 22 +- direct/src/plugin/make_package.py | 77 +++- direct/src/plugin/p3dInstanceManager.cxx | 10 +- direct/src/plugin/p3dInstanceManager.h | 3 +- direct/src/plugin/p3dPackage.I | 8 +- direct/src/plugin/p3dPackage.cxx | 32 +- direct/src/plugin/p3dPackage.h | 8 +- direct/src/plugin/p3dSession.cxx | 8 +- direct/src/plugin/p3dWinProgressWindow.cxx | 2 +- direct/src/plugin_npapi/nppanda3d.rc | 12 +- direct/src/plugin_npapi/nppanda3d_common.h | 3 + direct/src/plugin_npapi/nppanda3d_startup.cxx | 333 +++++++++++------- 14 files changed, 353 insertions(+), 168 deletions(-) diff --git a/direct/src/plugin/Sources.pp b/direct/src/plugin/Sources.pp index b48b328b56..3d06e60191 100644 --- a/direct/src/plugin/Sources.pp +++ b/direct/src/plugin/Sources.pp @@ -5,6 +5,7 @@ #begin lib_target #define USE_PACKAGES tinyxml openssl zlib #define TARGET p3d_plugin + #define LIB_PREFIX #define COMBINED_SOURCES \ $[TARGET]_composite1.cxx diff --git a/direct/src/plugin/load_plugin_src.cxx b/direct/src/plugin/load_plugin_src.cxx index 61cf7582e9..96bdf5ade9 100755 --- a/direct/src/plugin/load_plugin_src.cxx +++ b/direct/src/plugin/load_plugin_src.cxx @@ -30,7 +30,7 @@ static const string dll_ext = ".dylib"; static const string dll_ext = ".so"; #endif -static const string default_plugin_filename = "libp3d_plugin"; +static const string default_plugin_filename = "p3d_plugin"; P3D_initialize_func *P3D_initialize; P3D_free_string_func *P3D_free_string; diff --git a/direct/src/plugin/make_contents.py b/direct/src/plugin/make_contents.py index 272b00b932..d4b5cca156 100755 --- a/direct/src/plugin/make_contents.py +++ b/direct/src/plugin/make_contents.py @@ -53,9 +53,9 @@ class ContentsMaker: f = open(contentsFilePathname.toOsSpecific(), 'w') print >> f, '' print >> f, '' - for packageName, packageVersion, file in self.packages: - print >> f, '' % ( - packageName, packageVersion, file.getParams()) + for packageName, packageVersion, packagePlatform, file in self.packages: + print >> f, '' % ( + packageName, packageVersion, packagePlatform or '', file.getParams()) f.close() def scanDirectory(self): @@ -75,13 +75,25 @@ class ContentsMaker: localpath = dirpath[len(prefix):].replace(os.sep, '/') + '/' xml = dirpath[len(prefix):].replace(os.sep, '_') + '.xml' - if xml.count('_') == 1 and xml in filenames: + if xml not in filenames: + continue + + if xml.count('_') == 1: basename = xml.split('.')[0] packageName, packageVersion = basename.split('_') + packagePlatform = None file = FileSpec(localpath + xml, Filename(self.stageDir, localpath + xml)) print file.filename - self.packages.append((packageName, packageVersion, file)) + self.packages.append((packageName, packageVersion, packagePlatform, file)) + + if xml.count('_') == 2: + basename = xml.split('.')[0] + packageName, packageVersion, packagePlatform = basename.split('_') + file = FileSpec(localpath + xml, + Filename(self.stageDir, localpath + xml)) + print file.filename + self.packages.append((packageName, packageVersion, packagePlatform, file)) def makeContents(args): diff --git a/direct/src/plugin/make_package.py b/direct/src/plugin/make_package.py index 3e0937a124..3fbe79a8ee 100755 --- a/direct/src/plugin/make_package.py +++ b/direct/src/plugin/make_package.py @@ -23,10 +23,10 @@ Options: the local machine that will be filled with the contents of the package directory for the web server. - -p package_name - -v package_version + -p name_version[_platform] - Specify the name and version of the package to build. + Specify the package name, version, and optional platfom, of the + package to build. """ @@ -49,7 +49,9 @@ class PackageMaker: self.stageDir = None self.packageName = None self.packageVersion = None + self.packagePlatform = None + self.bogusExtensions = [] def build(self): if not self.startDir: @@ -59,11 +61,25 @@ class PackageMaker: if not self.packageName or not self.packageVersion: raise ArgumentError, "Package name and version not specified." + # First, scan the components. If we find any + # platform-dependent files, we automatically assume we're + # building a platform-specific package. + self.components = [] + self.findComponents() + + for ext in self.bogusExtensions: + print "Warning: Found files of type %s, inconsistent with declared platform %s" % ( + ext, self.packagePlatform) + self.packageFullname = '%s_%s' % ( self.packageName, self.packageVersion) self.packageStageDir = Filename(self.stageDir, '%s/%s' % (self.packageName, self.packageVersion)) + if self.packagePlatform: + self.packageFullname += '_%s' % (self.packagePlatform) + self.packageStageDir = Filename(self.packageStageDir, self.packagePlatform) + Filename(self.packageStageDir, '.').makeDir() self.cleanDir(self.packageStageDir) @@ -73,8 +89,6 @@ class PackageMaker: if not self.archive.openWrite(uncompressedArchivePathname): raise IOError, "Couldn't open %s for writing" % (uncompressedArchivePathname) - self.components = [] - self.addComponents() self.archive.close() @@ -106,7 +120,7 @@ class PackageMaker: f = open(descFilePathname.toOsSpecific(), 'w') print >> f, '' print >> f, '' - print >> f, '' % (self.packageName, self.packageVersion) + print >> f, '' % (self.packageName, self.packageVersion, self.packagePlatform or '') print >> f, ' ' % (uncompressedArchive.getParams()) print >> f, ' ' % (compressedArchive.getParams()) for file in self.components: @@ -123,9 +137,9 @@ class PackageMaker: pathname = Filename(dirname, filename) pathname.unlink() - def addComponents(self): + def findComponents(self): """ Walks through all the files in the start directory and - adds them to the archive. Recursively visits + adds them to self.components. Recursively visits sub-directories. """ startDir = self.startDir.toOsSpecific() @@ -142,12 +156,41 @@ class PackageMaker: for basename in filenames: file = FileSpec(localpath + basename, Filename(self.startDir, localpath + basename)) - print file.filename self.components.append(file) - self.archive.addSubfile(file.filename, file.pathname, 0) + print file.filename + + ext = os.path.splitext(basename)[1] + if ext in ['.exe', '.dll', '.pyd']: + self.ensurePlatform('win32', ext, file) + elif ext in ['.dylib']: + self.ensurePlatform('osx', ext, file) + elif ext in ['.so']: + self.ensurePlatform(None, ext, file) + + def ensurePlatform(self, platform, ext, file): + """ We have just encountered a file that is specific to a + particular platform. Checks that the declared platform is + consistent with this. """ + + if platform and self.packagePlatform: + if self.packagePlatform.startswith(platform): + # This platform is consistent with our declared + # platform. + return + + if ext in self.bogusExtensions: + # Already reported this one. + return + + self.bogusExtensions.append(ext) + + + def addComponents(self): + for file in self.components: + self.archive.addSubfile(file.filename, file.pathname, 0) def makePackage(args): - opts, args = getopt.getopt(args, 's:d:p:v:h') + opts, args = getopt.getopt(args, 's:d:p:h') pm = PackageMaker() pm.startDir = Filename('.') @@ -157,9 +200,15 @@ def makePackage(args): elif option == '-d': pm.stageDir = Filename.fromOsSpecific(value) elif option == '-p': - pm.packageName = value - elif option == '-v': - pm.packageVersion = value + tokens = value.split('_') + if len(tokens) >= 1: + pm.packageName = tokens[0] + if len(tokens) >= 2: + pm.packageVersion = tokens[1] + if len(tokens) >= 3: + pm.packagePlatform = tokens[2] + if len(tokens) >= 4: + raise ArgumentError, 'Too many tokens in string: %s' % (value) elif option == '-h': print __doc__ diff --git a/direct/src/plugin/p3dInstanceManager.cxx b/direct/src/plugin/p3dInstanceManager.cxx index 571087f9d8..043c3d2549 100644 --- a/direct/src/plugin/p3dInstanceManager.cxx +++ b/direct/src/plugin/p3dInstanceManager.cxx @@ -95,7 +95,7 @@ initialize() { #ifdef _WIN32 // _download_url = "http://10.196.143.118/~drose/p3d/"; - _download_url = "http://www.ddrose.com/~drose/p3dwin/"; + _download_url = "http://www.ddrose.com/~drose/p3d/"; #else _download_url = "http://www.ddrose.com/~drose/p3d/"; @@ -239,14 +239,16 @@ wait_request() { // package. //////////////////////////////////////////////////////////////////// P3DPackage *P3DInstanceManager:: -get_package(const string &package_name, const string &package_version, const string &package_output_name) { - string key = package_name + "_" + package_version; +get_package(const string &package_name, const string &package_version, + const string &package_platform, const string &package_display_name) { + string key = package_name + "_" + package_version + "_" + package_platform; Packages::iterator pi = _packages.find(key); if (pi != _packages.end()) { return (*pi).second; } - P3DPackage *package = new P3DPackage(package_name, package_version, package_output_name); + P3DPackage *package = new P3DPackage(package_name, package_version, + package_platform, package_display_name); bool inserted = _packages.insert(Packages::value_type(key, package)).second; assert(inserted); diff --git a/direct/src/plugin/p3dInstanceManager.h b/direct/src/plugin/p3dInstanceManager.h index 952dd54ea2..e418f35f1a 100644 --- a/direct/src/plugin/p3dInstanceManager.h +++ b/direct/src/plugin/p3dInstanceManager.h @@ -55,7 +55,8 @@ public: P3DPackage *get_package(const string &package_name, const string &package_version, - const string &package_output_name); + const string &package_platform, + const string &package_display_name); inline P3DInstance *get_command_instance() const; inline int get_num_instances() const; diff --git a/direct/src/plugin/p3dPackage.I b/direct/src/plugin/p3dPackage.I index 276276d686..2e4db4edcb 100755 --- a/direct/src/plugin/p3dPackage.I +++ b/direct/src/plugin/p3dPackage.I @@ -53,7 +53,7 @@ get_package_dir() const { // Description: Returns the name of this package. This is an // internal name, used to generate filenames and the // like; it will generally be all-lowercase and will not -// contain spaces. See also get_package_output_name() +// contain spaces. See also get_package_display_name() // for a name suitable for displaying to the user. //////////////////////////////////////////////////////////////////// inline const string &P3DPackage:: @@ -72,7 +72,7 @@ get_package_version() const { } //////////////////////////////////////////////////////////////////// -// Function: P3DPackage::get_package_output_name +// Function: P3DPackage::get_package_display_name // Access: Public // Description: Returns the name of this package, for output to the // user. This will be the "public" name of the package, @@ -80,8 +80,8 @@ get_package_version() const { // capital letters and spaces where appropriate. //////////////////////////////////////////////////////////////////// inline const string &P3DPackage:: -get_package_output_name() const { - return _package_output_name; +get_package_display_name() const { + return _package_display_name; } //////////////////////////////////////////////////////////////////// diff --git a/direct/src/plugin/p3dPackage.cxx b/direct/src/plugin/p3dPackage.cxx index fb01d6a5d4..e35fbe8dc5 100755 --- a/direct/src/plugin/p3dPackage.cxx +++ b/direct/src/plugin/p3dPackage.cxx @@ -51,21 +51,29 @@ static const double extract_portion = 0.05; //////////////////////////////////////////////////////////////////// P3DPackage:: P3DPackage(const string &package_name, const string &package_version, - const string &package_output_name) : + const string &package_platform, + const string &package_display_name) : _package_name(package_name), _package_version(package_version), - _package_output_name(package_output_name) + _package_platform(package_platform), + _package_display_name(package_display_name) { + P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); + _package_fullname = _package_name + "_" + _package_version; + _package_dir = inst_mgr->get_root_dir() + string("/") + _package_name; + + if (!_package_platform.empty()) { + _package_fullname += "_" + _package_platform; + _package_dir += "/" + _package_platform; + } + _ready = false; _failed = false; _active_download = NULL; _partial_download = false; - P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); - // Ensure the package directory exists; create it if it does not. - _package_dir = inst_mgr->get_root_dir() + string("/") + _package_name; inst_mgr->mkdir_public(_package_dir); _package_dir += string("/") + _package_version; @@ -156,7 +164,12 @@ void P3DPackage:: download_desc_file() { P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); string url = inst_mgr->get_download_url(); - url += _package_name + "/" + _package_version + "/" + _desc_file_basename; + url += _package_name + "/" + _package_version; + if (!_package_platform.empty()) { + url += "/" + _package_platform; + } + + url += "/" + _desc_file_basename; start_download(DT_desc_file, url, _desc_file_pathname, false); } @@ -263,7 +276,12 @@ void P3DPackage:: download_compressed_archive(bool allow_partial) { P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); string url = inst_mgr->get_download_url(); - url += _package_name + "/" + _package_version + "/" + _compressed_archive._filename; + url += _package_name + "/" + _package_version; + if (!_package_platform.empty()) { + url += "/" + _package_platform; + } + + url += "/" + _compressed_archive._filename; string target_pathname = _package_dir + "/" + _compressed_archive._filename; diff --git a/direct/src/plugin/p3dPackage.h b/direct/src/plugin/p3dPackage.h index b5b05cce96..1e8e362e23 100755 --- a/direct/src/plugin/p3dPackage.h +++ b/direct/src/plugin/p3dPackage.h @@ -33,7 +33,8 @@ class P3DPackage { public: P3DPackage(const string &package_name, const string &package_version, - const string &package_output_name); + const string &package_platform, + const string &package_display_name); ~P3DPackage(); class Callback { @@ -48,7 +49,7 @@ public: inline const string &get_package_dir() const; inline const string &get_package_name() const; inline const string &get_package_version() const; - inline const string &get_package_output_name() const; + inline const string &get_package_display_name() const; void set_callback(Callback *callback); void cancel_callback(Callback *callback); @@ -98,7 +99,8 @@ private: private: string _package_name; string _package_version; - string _package_output_name; + string _package_platform; + string _package_display_name; string _package_fullname; string _package_dir; diff --git a/direct/src/plugin/p3dSession.cxx b/direct/src/plugin/p3dSession.cxx index f87bedea3d..ec23fcb7bb 100644 --- a/direct/src/plugin/p3dSession.cxx +++ b/direct/src/plugin/p3dSession.cxx @@ -50,7 +50,13 @@ P3DSession(P3DInstance *inst) { P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); - _panda3d = inst_mgr->get_package("panda3d", "dev", "Panda3D"); +#ifdef _WIN32 + string platform = "win32"; +#else + string platform = "osx_i386"; +#endif + + _panda3d = inst_mgr->get_package("panda3d", "dev", platform, "Panda3D"); _panda3d_callback = NULL; _python_root_dir = _panda3d->get_package_dir(); diff --git a/direct/src/plugin/p3dWinProgressWindow.cxx b/direct/src/plugin/p3dWinProgressWindow.cxx index 72dd554613..4aeba97a33 100755 --- a/direct/src/plugin/p3dWinProgressWindow.cxx +++ b/direct/src/plugin/p3dWinProgressWindow.cxx @@ -280,7 +280,7 @@ make_progress_bar() { _hwnd, NULL, application, 0); // Create a static text label. What a major pain *this* is. - string text_string = "Installing " + _package->get_package_output_name(); + string text_string = "Installing " + _package->get_package_display_name(); const char *text = text_string.c_str(); HFONT font = (HFONT)GetStockObject(ANSI_VAR_FONT); diff --git a/direct/src/plugin_npapi/nppanda3d.rc b/direct/src/plugin_npapi/nppanda3d.rc index 302e11bf1f..a60f372c23 100644 --- a/direct/src/plugin_npapi/nppanda3d.rc +++ b/direct/src/plugin_npapi/nppanda3d.rc @@ -32,21 +32,15 @@ BEGIN BEGIN BLOCK "040904e4" BEGIN - VALUE "Comments", "\0" - VALUE "CompanyName", " \0" - VALUE "FileDescription", "nppanda3d\0" - VALUE "FileExtents", "bic\0" - VALUE "FileOpenName", "nppanda3d\0" + VALUE "FileDescription", "Runs 3-D games and interactive applets\0" VALUE "FileVersion", "1, 0, 0, 1\0" - VALUE "InternalName", "nppanda3d\0" - VALUE "LegalCopyright", "Copyright © 2001\0" VALUE "LegalTrademarks", "\0" VALUE "MIMEType", "application/x-panda3d\0" + VALUE "FileExtents", "p3d\0" + VALUE "FileOpenName", "Panda3D applet\0" VALUE "OriginalFilename", "nppanda3d.dll\0" - VALUE "PrivateBuild", "\0" VALUE "ProductName", "Panda3D Game Engine Plug-in\0" VALUE "ProductVersion", "1, 0, 0, 1\0" - VALUE "SpecialBuild", "\0" END END BLOCK "VarFileInfo" diff --git a/direct/src/plugin_npapi/nppanda3d_common.h b/direct/src/plugin_npapi/nppanda3d_common.h index 418726c420..58810e6720 100644 --- a/direct/src/plugin_npapi/nppanda3d_common.h +++ b/direct/src/plugin_npapi/nppanda3d_common.h @@ -57,5 +57,8 @@ extern ofstream logfile; //#include "npfunctions.h" #include "npupp.h" +// Appears in nppanda3d_startup.cxx. +extern NPNetscapeFuncs *browser; + #endif diff --git a/direct/src/plugin_npapi/nppanda3d_startup.cxx b/direct/src/plugin_npapi/nppanda3d_startup.cxx index bcdd5c5acf..2eaf5431c1 100644 --- a/direct/src/plugin_npapi/nppanda3d_startup.cxx +++ b/direct/src/plugin_npapi/nppanda3d_startup.cxx @@ -21,7 +21,10 @@ #endif ofstream logfile; -bool logfile_is_open = false; + +NPNetscapeFuncs *browser; + +static bool logfile_is_open = false; static void open_logfile() { if (!logfile_is_open) { @@ -34,119 +37,13 @@ open_logfile() { } } - -// structure containing pointers to functions implemented by the browser -static NPNetscapeFuncs *browser; - -// Called to create a new instance of the plugin -NPError -NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, - int16 argc, char *argn[], char *argv[], NPSavedData *saved) { - logfile << "new instance\n" << flush; - - // Copy the tokens into a temporary array of P3D_token objects. - P3D_token *tokens = (P3D_token *)alloca(sizeof(P3D_token) * argc); - for (int i = 0; i < argc; ++i) { - P3D_token &token = tokens[i]; - token._keyword = argn[i]; - token._value = argv[i]; - logfile << " " << i << ": " << token._keyword << " = " << token._value << "\n"; - } - - instance->pdata = P3D_create_instance(NULL, NULL, tokens, argc); - - return NPERR_NO_ERROR; -} - -// Called to destroy an instance of the plugin -NPError -NPP_Destroy(NPP instance, NPSavedData **save) { - logfile << "destroy instance\n" << flush; - (*save) = NULL; - P3D_instance_finish((P3D_instance *)(instance->pdata)); - instance->pdata = NULL; - - return NPERR_NO_ERROR; -} - -// Called to update a plugin instances's NPWindow -NPError -NPP_SetWindow(NPP instance, NPWindow *window) { - logfile << "SetWindow " << window->x << ", " << window->y - << ", " << window->width << ", " << window->height - << "\n" << flush; - - P3D_instance *inst = (P3D_instance *)(instance->pdata); - assert(inst != NULL); - - P3D_window_handle parent_window; -#ifdef _WIN32 - parent_window._hwnd = (HWND)(window->window); -#endif - - P3D_window_type window_type = P3D_WT_embedded; - - P3D_instance_setup_window - (inst, window_type, - window->x, window->y, window->width, window->height, - parent_window); - - return NPERR_NO_ERROR; -} - - -NPError -NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, - NPBool seekable, uint16 *stype) { - *stype = NP_ASFILEONLY; - return NPERR_NO_ERROR; -} - -NPError -NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason) { - return NPERR_NO_ERROR; -} - -int32 -NPP_WriteReady(NPP instance, NPStream *stream) { - return 0; -} - -int32 -NPP_Write(NPP instance, NPStream *stream, int32 offset, - int32 len, void *buffer) { - return 0; -} - -void -NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname) { -} - -void -NPP_Print(NPP instance, NPPrint *platformPrint) { -} - -int16 -NPP_HandleEvent(NPP instance, void *event) { - return 0; -} - -void -NPP_URLNotify(NPP instance, const char *url, - NPReason reason, void *notifyData) { -} - -NPError -NPP_GetValue(NPP instance, NPPVariable variable, void *value) { - return NPERR_GENERIC_ERROR; -} - -NPError -NPP_SetValue(NPP instance, NPNVariable variable, void *value) { - return NPERR_GENERIC_ERROR; -} - -// Symbol called once by the browser to initialize the plugin +//////////////////////////////////////////////////////////////////// +// Function: NP_Initialize +// Description: This function is called (almost) before any other +// function, to ask the plugin to initialize itself and +// to send the pointers to the browser control +// functions. Also see NP_GetEntryPoints. +//////////////////////////////////////////////////////////////////// #ifdef _WIN32 NPError OSCALL NP_Initialize(NPNetscapeFuncs *browserFuncs) @@ -168,9 +65,9 @@ NP_Initialize(NPNetscapeFuncs *browserFuncs, logfile << "browserFuncs = " << browserFuncs << "\n" << flush; #ifdef _WIN32 - string plugin_location = "c:/cygwin/home/drose/player/direct/built/lib/libp3d_plugin.dll"; + string plugin_location = "c:/cygwin/home/drose/player/direct/built/lib/p3d_plugin.dll"; #else - string plugin_location = "/Users/drose/player/direct/built/lib/libp3d_plugin.dylib"; + string plugin_location = "/Users/drose/player/direct/built/lib/p3d_plugin.dylib"; #endif if (!load_plugin(plugin_location.c_str())) { @@ -181,7 +78,14 @@ NP_Initialize(NPNetscapeFuncs *browserFuncs, return NPERR_NO_ERROR; } -// Symbol called by the browser to get the plugin's function list +//////////////////////////////////////////////////////////////////// +// Function: NP_GetEntryPoints +// Description: This method is extracted directly from the DLL and +// called at initialization time by the browser, either +// before or after NP_Initialize, to retrieve the +// pointers to the rest of the plugin functions that are +// not exported from the DLL. +//////////////////////////////////////////////////////////////////// NPError OSCALL NP_GetEntryPoints(NPPluginFuncs *pluginFuncs) { open_logfile(); @@ -206,11 +110,204 @@ NP_GetEntryPoints(NPPluginFuncs *pluginFuncs) { return NPERR_NO_ERROR; } -// Symbol called once by the browser to shut down the plugin +//////////////////////////////////////////////////////////////////// +// Function: NP_Shutdown +// Description: This function is called when the browser is done with +// the plugin; it asks the plugin to unload itself and +// free all used resources. +//////////////////////////////////////////////////////////////////// NPError OSCALL NP_Shutdown(void) { logfile << "shutdown\n" << flush; unload_plugin(); + // Not clear whether there's a return value or not. Some versions + // of the API have different opinions on this. return NPERR_NO_ERROR; } + +//////////////////////////////////////////////////////////////////// +// Function: NPP_New +// Description: Called by the browser to create a new instance of the +// plugin. +//////////////////////////////////////////////////////////////////// +NPError +NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, + int16 argc, char *argn[], char *argv[], NPSavedData *saved) { + logfile << "new instance\n" << flush; + + // Copy the tokens into a temporary array of P3D_token objects. + P3D_token *tokens = (P3D_token *)alloca(sizeof(P3D_token) * argc); + for (int i = 0; i < argc; ++i) { + P3D_token &token = tokens[i]; + token._keyword = argn[i]; + token._value = argv[i]; + logfile << " " << i << ": " << token._keyword << " = " << token._value << "\n"; + } + + instance->pdata = P3D_create_instance(NULL, NULL, tokens, argc); + + return NPERR_NO_ERROR; +} + +//////////////////////////////////////////////////////////////////// +// Function: NPP_Destroy +// Description: Called by the browser to destroy an instance of the +// plugin previously created with NPP_New. +//////////////////////////////////////////////////////////////////// +NPError +NPP_Destroy(NPP instance, NPSavedData **save) { + logfile << "destroy instance\n" << flush; + (*save) = NULL; + P3D_instance_finish((P3D_instance *)(instance->pdata)); + instance->pdata = NULL; + + return NPERR_NO_ERROR; +} + +//////////////////////////////////////////////////////////////////// +// Function: NPP_SetWindow +// Description: Called by the browser to inform the instance of its +// window size and placement. This is called initially +// to create the window, and may be called subsequently +// when the window needs to be moved. It may be called +// redundantly. +//////////////////////////////////////////////////////////////////// +NPError +NPP_SetWindow(NPP instance, NPWindow *window) { + logfile << "SetWindow " << window->x << ", " << window->y + << ", " << window->width << ", " << window->height + << "\n" << flush; + + P3D_instance *inst = (P3D_instance *)(instance->pdata); + assert(inst != NULL); + + P3D_window_handle parent_window; +#ifdef _WIN32 + parent_window._hwnd = (HWND)(window->window); +#endif + + P3D_instance_setup_window + (inst, P3D_WT_embedded, + window->x, window->y, window->width, window->height, + parent_window); + + return NPERR_NO_ERROR; +} + +//////////////////////////////////////////////////////////////////// +// Function: NPP_NewStream +// Description: Called by the browser when a new data stream is +// created, usually in response to a geturl request; but +// it is also called initially to supply the data in the +// data or src element. The plugin must specify how it +// can receive the stream. +//////////////////////////////////////////////////////////////////// +NPError +NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, + NPBool seekable, uint16 *stype) { + logfile << "NewStream " << type << ", " << stream->url + << ", " << stream->end << "\n" << flush; + *stype = NP_ASFILEONLY; + return NPERR_NO_ERROR; +} + +//////////////////////////////////////////////////////////////////// +// Function: NPP_DestroyStream +// Description: Called by the browser to mark the end of a stream +// created with NewStream. +//////////////////////////////////////////////////////////////////// +NPError +NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason) { + logfile << "DestroyStream\n" << flush; + return NPERR_NO_ERROR; +} + +//////////////////////////////////////////////////////////////////// +// Function: NPP_WriteReady +// Description: Called by the browser to ask how many bytes it can +// deliver for a stream. +//////////////////////////////////////////////////////////////////// +int32 +NPP_WriteReady(NPP instance, NPStream *stream) { + logfile << "WriteReady\n"; + return 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: NPP_Write +// Description: Called by the browser to deliver bytes for the +// stream; the plugin should return the number of bytes +// consumed. +//////////////////////////////////////////////////////////////////// +int32 +NPP_Write(NPP instance, NPStream *stream, int32 offset, + int32 len, void *buffer) { + logfile << "Write\n"; + return 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: NPP_StreamAsFile +// Description: Called by the browser to report the filename that +// contains the fully-downloaded stream, if +// NP_ASFILEONLY was specified by the plugin in +// NPP_NewStream. +//////////////////////////////////////////////////////////////////// +void +NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname) { + logfile << "StreamAsFile: " << fname << "\n" << flush; +} + +//////////////////////////////////////////////////////////////////// +// Function: NPP_Print +// Description: Called by the browser when the user attempts to print +// the page containing the plugin instance. +//////////////////////////////////////////////////////////////////// +void +NPP_Print(NPP instance, NPPrint *platformPrint) { + logfile << "Print\n"; +} + +//////////////////////////////////////////////////////////////////// +// Function: NPP_HandleEvent +// Description: Called by the browser to inform the plugin of OS +// window events. +//////////////////////////////////////////////////////////////////// +int16 +NPP_HandleEvent(NPP instance, void *event) { + logfile << "HandleEvent\n"; + return 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: NPP_URLNotify +// Description: Called by the browser to inform the plugin of a +// completed URL request. +//////////////////////////////////////////////////////////////////// +void +NPP_URLNotify(NPP instance, const char *url, + NPReason reason, void *notifyData) { + logfile << "URLNotify: " << url << "\n"; +} + +//////////////////////////////////////////////////////////////////// +// Function: NPP_GetValue +// Description: Called by the browser to query specific information +// from the plugin. +//////////////////////////////////////////////////////////////////// +NPError +NPP_GetValue(NPP instance, NPPVariable variable, void *value) { + logfile << "GetValue " << variable << "\n"; + return NPERR_GENERIC_ERROR; +} + +//////////////////////////////////////////////////////////////////// +// Function: NPP_URLNotify +// Description: Called by the browser to update a scriptable value. +//////////////////////////////////////////////////////////////////// +NPError +NPP_SetValue(NPP instance, NPNVariable variable, void *value) { + logfile << "SetValue " << variable << "\n"; + return NPERR_GENERIC_ERROR; +}