more work

This commit is contained in:
David Rose 2009-06-23 02:11:32 +00:00
parent 71d65bb60c
commit 6c73c0d08d
14 changed files with 353 additions and 168 deletions

View File

@ -5,6 +5,7 @@
#begin lib_target #begin lib_target
#define USE_PACKAGES tinyxml openssl zlib #define USE_PACKAGES tinyxml openssl zlib
#define TARGET p3d_plugin #define TARGET p3d_plugin
#define LIB_PREFIX
#define COMBINED_SOURCES \ #define COMBINED_SOURCES \
$[TARGET]_composite1.cxx $[TARGET]_composite1.cxx

View File

@ -30,7 +30,7 @@ static const string dll_ext = ".dylib";
static const string dll_ext = ".so"; static const string dll_ext = ".so";
#endif #endif
static const string default_plugin_filename = "libp3d_plugin"; static const string default_plugin_filename = "p3d_plugin";
P3D_initialize_func *P3D_initialize; P3D_initialize_func *P3D_initialize;
P3D_free_string_func *P3D_free_string; P3D_free_string_func *P3D_free_string;

View File

@ -53,9 +53,9 @@ class ContentsMaker:
f = open(contentsFilePathname.toOsSpecific(), 'w') f = open(contentsFilePathname.toOsSpecific(), 'w')
print >> f, '<?xml version="1.0" ?>' print >> f, '<?xml version="1.0" ?>'
print >> f, '' print >> f, ''
for packageName, packageVersion, file in self.packages: for packageName, packageVersion, packagePlatform, file in self.packages:
print >> f, '<package name="%s" version="%s" %s />' % ( print >> f, '<package name="%s" version="%s" platform="%s" %s />' % (
packageName, packageVersion, file.getParams()) packageName, packageVersion, packagePlatform or '', file.getParams())
f.close() f.close()
def scanDirectory(self): def scanDirectory(self):
@ -75,13 +75,25 @@ class ContentsMaker:
localpath = dirpath[len(prefix):].replace(os.sep, '/') + '/' localpath = dirpath[len(prefix):].replace(os.sep, '/') + '/'
xml = dirpath[len(prefix):].replace(os.sep, '_') + '.xml' 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] basename = xml.split('.')[0]
packageName, packageVersion = basename.split('_') packageName, packageVersion = basename.split('_')
packagePlatform = None
file = FileSpec(localpath + xml, file = FileSpec(localpath + xml,
Filename(self.stageDir, localpath + xml)) Filename(self.stageDir, localpath + xml))
print file.filename 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): def makeContents(args):

View File

@ -23,10 +23,10 @@ Options:
the local machine that will be filled with the contents of the the local machine that will be filled with the contents of the
package directory for the web server. package directory for the web server.
-p package_name -p name_version[_platform]
-v package_version
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.stageDir = None
self.packageName = None self.packageName = None
self.packageVersion = None self.packageVersion = None
self.packagePlatform = None
self.bogusExtensions = []
def build(self): def build(self):
if not self.startDir: if not self.startDir:
@ -59,11 +61,25 @@ class PackageMaker:
if not self.packageName or not self.packageVersion: if not self.packageName or not self.packageVersion:
raise ArgumentError, "Package name and version not specified." 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.packageFullname = '%s_%s' % (
self.packageName, self.packageVersion) self.packageName, self.packageVersion)
self.packageStageDir = Filename(self.stageDir, '%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() Filename(self.packageStageDir, '.').makeDir()
self.cleanDir(self.packageStageDir) self.cleanDir(self.packageStageDir)
@ -73,8 +89,6 @@ class PackageMaker:
if not self.archive.openWrite(uncompressedArchivePathname): if not self.archive.openWrite(uncompressedArchivePathname):
raise IOError, "Couldn't open %s for writing" % (uncompressedArchivePathname) raise IOError, "Couldn't open %s for writing" % (uncompressedArchivePathname)
self.components = []
self.addComponents() self.addComponents()
self.archive.close() self.archive.close()
@ -106,7 +120,7 @@ class PackageMaker:
f = open(descFilePathname.toOsSpecific(), 'w') f = open(descFilePathname.toOsSpecific(), 'w')
print >> f, '<?xml version="1.0" ?>' print >> f, '<?xml version="1.0" ?>'
print >> f, '' print >> f, ''
print >> f, '<package name="%s" version="%s">' % (self.packageName, self.packageVersion) print >> f, '<package name="%s" version="%s" platform="%s">' % (self.packageName, self.packageVersion, self.packagePlatform or '')
print >> f, ' <uncompressed_archive %s />' % (uncompressedArchive.getParams()) print >> f, ' <uncompressed_archive %s />' % (uncompressedArchive.getParams())
print >> f, ' <compressed_archive %s />' % (compressedArchive.getParams()) print >> f, ' <compressed_archive %s />' % (compressedArchive.getParams())
for file in self.components: for file in self.components:
@ -123,9 +137,9 @@ class PackageMaker:
pathname = Filename(dirname, filename) pathname = Filename(dirname, filename)
pathname.unlink() pathname.unlink()
def addComponents(self): def findComponents(self):
""" Walks through all the files in the start directory and """ 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. """ sub-directories. """
startDir = self.startDir.toOsSpecific() startDir = self.startDir.toOsSpecific()
@ -142,12 +156,41 @@ class PackageMaker:
for basename in filenames: for basename in filenames:
file = FileSpec(localpath + basename, file = FileSpec(localpath + basename,
Filename(self.startDir, localpath + basename)) Filename(self.startDir, localpath + basename))
print file.filename
self.components.append(file) 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): 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 = PackageMaker()
pm.startDir = Filename('.') pm.startDir = Filename('.')
@ -157,9 +200,15 @@ def makePackage(args):
elif option == '-d': elif option == '-d':
pm.stageDir = Filename.fromOsSpecific(value) pm.stageDir = Filename.fromOsSpecific(value)
elif option == '-p': elif option == '-p':
pm.packageName = value tokens = value.split('_')
elif option == '-v': if len(tokens) >= 1:
pm.packageVersion = value 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': elif option == '-h':
print __doc__ print __doc__

View File

@ -95,7 +95,7 @@ initialize() {
#ifdef _WIN32 #ifdef _WIN32
// _download_url = "http://10.196.143.118/~drose/p3d/"; // _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 #else
_download_url = "http://www.ddrose.com/~drose/p3d/"; _download_url = "http://www.ddrose.com/~drose/p3d/";
@ -239,14 +239,16 @@ wait_request() {
// package. // package.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
P3DPackage *P3DInstanceManager:: P3DPackage *P3DInstanceManager::
get_package(const string &package_name, const string &package_version, const string &package_output_name) { get_package(const string &package_name, const string &package_version,
string key = package_name + "_" + 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); Packages::iterator pi = _packages.find(key);
if (pi != _packages.end()) { if (pi != _packages.end()) {
return (*pi).second; 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; bool inserted = _packages.insert(Packages::value_type(key, package)).second;
assert(inserted); assert(inserted);

View File

@ -55,7 +55,8 @@ public:
P3DPackage *get_package(const string &package_name, P3DPackage *get_package(const string &package_name,
const string &package_version, 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 P3DInstance *get_command_instance() const;
inline int get_num_instances() const; inline int get_num_instances() const;

View File

@ -53,7 +53,7 @@ get_package_dir() const {
// Description: Returns the name of this package. This is an // Description: Returns the name of this package. This is an
// internal name, used to generate filenames and the // internal name, used to generate filenames and the
// like; it will generally be all-lowercase and will not // 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. // for a name suitable for displaying to the user.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
inline const string &P3DPackage:: 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 // Access: Public
// Description: Returns the name of this package, for output to the // Description: Returns the name of this package, for output to the
// user. This will be the "public" name of the package, // user. This will be the "public" name of the package,
@ -80,8 +80,8 @@ get_package_version() const {
// capital letters and spaces where appropriate. // capital letters and spaces where appropriate.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
inline const string &P3DPackage:: inline const string &P3DPackage::
get_package_output_name() const { get_package_display_name() const {
return _package_output_name; return _package_display_name;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -51,21 +51,29 @@ static const double extract_portion = 0.05;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
P3DPackage:: P3DPackage::
P3DPackage(const string &package_name, const string &package_version, 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_name(package_name),
_package_version(package_version), _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_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; _ready = false;
_failed = false; _failed = false;
_active_download = NULL; _active_download = NULL;
_partial_download = false; _partial_download = false;
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
// Ensure the package directory exists; create it if it does not. // 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); inst_mgr->mkdir_public(_package_dir);
_package_dir += string("/") + _package_version; _package_dir += string("/") + _package_version;
@ -156,7 +164,12 @@ void P3DPackage::
download_desc_file() { download_desc_file() {
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
string url = inst_mgr->get_download_url(); 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); start_download(DT_desc_file, url, _desc_file_pathname, false);
} }
@ -263,7 +276,12 @@ void P3DPackage::
download_compressed_archive(bool allow_partial) { download_compressed_archive(bool allow_partial) {
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
string url = inst_mgr->get_download_url(); 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; string target_pathname = _package_dir + "/" + _compressed_archive._filename;

View File

@ -33,7 +33,8 @@
class P3DPackage { class P3DPackage {
public: public:
P3DPackage(const string &package_name, const string &package_version, P3DPackage(const string &package_name, const string &package_version,
const string &package_output_name); const string &package_platform,
const string &package_display_name);
~P3DPackage(); ~P3DPackage();
class Callback { class Callback {
@ -48,7 +49,7 @@ public:
inline const string &get_package_dir() const; inline const string &get_package_dir() const;
inline const string &get_package_name() const; inline const string &get_package_name() const;
inline const string &get_package_version() 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 set_callback(Callback *callback);
void cancel_callback(Callback *callback); void cancel_callback(Callback *callback);
@ -98,7 +99,8 @@ private:
private: private:
string _package_name; string _package_name;
string _package_version; string _package_version;
string _package_output_name; string _package_platform;
string _package_display_name;
string _package_fullname; string _package_fullname;
string _package_dir; string _package_dir;

View File

@ -50,7 +50,13 @@ P3DSession(P3DInstance *inst) {
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); 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; _panda3d_callback = NULL;
_python_root_dir = _panda3d->get_package_dir(); _python_root_dir = _panda3d->get_package_dir();

View File

@ -280,7 +280,7 @@ make_progress_bar() {
_hwnd, NULL, application, 0); _hwnd, NULL, application, 0);
// Create a static text label. What a major pain *this* is. // 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(); const char *text = text_string.c_str();
HFONT font = (HFONT)GetStockObject(ANSI_VAR_FONT); HFONT font = (HFONT)GetStockObject(ANSI_VAR_FONT);

View File

@ -32,21 +32,15 @@ BEGIN
BEGIN BEGIN
BLOCK "040904e4" BLOCK "040904e4"
BEGIN BEGIN
VALUE "Comments", "\0" VALUE "FileDescription", "Runs 3-D games and interactive applets\0"
VALUE "CompanyName", " \0"
VALUE "FileDescription", "nppanda3d\0"
VALUE "FileExtents", "bic\0"
VALUE "FileOpenName", "nppanda3d\0"
VALUE "FileVersion", "1, 0, 0, 1\0" VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "nppanda3d\0"
VALUE "LegalCopyright", "Copyright © 2001\0"
VALUE "LegalTrademarks", "\0" VALUE "LegalTrademarks", "\0"
VALUE "MIMEType", "application/x-panda3d\0" VALUE "MIMEType", "application/x-panda3d\0"
VALUE "FileExtents", "p3d\0"
VALUE "FileOpenName", "Panda3D applet\0"
VALUE "OriginalFilename", "nppanda3d.dll\0" VALUE "OriginalFilename", "nppanda3d.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "Panda3D Game Engine Plug-in\0" VALUE "ProductName", "Panda3D Game Engine Plug-in\0"
VALUE "ProductVersion", "1, 0, 0, 1\0" VALUE "ProductVersion", "1, 0, 0, 1\0"
VALUE "SpecialBuild", "\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -57,5 +57,8 @@ extern ofstream logfile;
//#include "npfunctions.h" //#include "npfunctions.h"
#include "npupp.h" #include "npupp.h"
// Appears in nppanda3d_startup.cxx.
extern NPNetscapeFuncs *browser;
#endif #endif

View File

@ -21,7 +21,10 @@
#endif #endif
ofstream logfile; ofstream logfile;
bool logfile_is_open = false;
NPNetscapeFuncs *browser;
static bool logfile_is_open = false;
static void static void
open_logfile() { open_logfile() {
if (!logfile_is_open) { if (!logfile_is_open) {
@ -34,119 +37,13 @@ open_logfile() {
} }
} }
////////////////////////////////////////////////////////////////////
// structure containing pointers to functions implemented by the browser // Function: NP_Initialize
static NPNetscapeFuncs *browser; // Description: This function is called (almost) before any other
// function, to ask the plugin to initialize itself and
// Called to create a new instance of the plugin // to send the pointers to the browser control
NPError // functions. Also see NP_GetEntryPoints.
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
#ifdef _WIN32 #ifdef _WIN32
NPError OSCALL NPError OSCALL
NP_Initialize(NPNetscapeFuncs *browserFuncs) NP_Initialize(NPNetscapeFuncs *browserFuncs)
@ -168,9 +65,9 @@ NP_Initialize(NPNetscapeFuncs *browserFuncs,
logfile << "browserFuncs = " << browserFuncs << "\n" << flush; logfile << "browserFuncs = " << browserFuncs << "\n" << flush;
#ifdef _WIN32 #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 #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 #endif
if (!load_plugin(plugin_location.c_str())) { if (!load_plugin(plugin_location.c_str())) {
@ -181,7 +78,14 @@ NP_Initialize(NPNetscapeFuncs *browserFuncs,
return NPERR_NO_ERROR; 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 NPError OSCALL
NP_GetEntryPoints(NPPluginFuncs *pluginFuncs) { NP_GetEntryPoints(NPPluginFuncs *pluginFuncs) {
open_logfile(); open_logfile();
@ -206,11 +110,204 @@ NP_GetEntryPoints(NPPluginFuncs *pluginFuncs) {
return NPERR_NO_ERROR; 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 NPError OSCALL
NP_Shutdown(void) { NP_Shutdown(void) {
logfile << "shutdown\n" << flush; logfile << "shutdown\n" << flush;
unload_plugin(); 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; 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;
}