diff --git a/direct/src/plugin/Sources.pp b/direct/src/plugin/Sources.pp index 141f720246..48bfef0f73 100644 --- a/direct/src/plugin/Sources.pp +++ b/direct/src/plugin/Sources.pp @@ -36,6 +36,7 @@ p3dInstance.h p3dInstance.I \ p3dInstanceManager.h p3dInstanceManager.I \ p3dIntObject.h \ + p3dMainObject.h \ p3dMultifileReader.h p3dMultifileReader.I \ p3dNoneObject.h \ p3dObject.h p3dObject.I \ @@ -47,7 +48,6 @@ p3dSplashWindow.h p3dSplashWindow.I \ p3dStringObject.h \ p3dTemporaryFile.h p3dTemporaryFile.I \ - p3dToplevelObject.h \ p3dUndefinedObject.h \ p3dWinSplashWindow.h p3dWinSplashWindow.I \ p3dX11SplashWindow.h \ @@ -67,6 +67,7 @@ p3dInstance.cxx \ p3dInstanceManager.cxx \ p3dIntObject.cxx \ + p3dMainObject.cxx \ p3dMultifileReader.cxx \ p3dNoneObject.cxx \ p3dObject.cxx \ @@ -78,7 +79,6 @@ p3dSplashWindow.cxx \ p3dStringObject.cxx \ p3dTemporaryFile.cxx \ - p3dToplevelObject.cxx \ p3dUndefinedObject.cxx \ p3dWinSplashWindow.cxx \ p3dX11SplashWindow.cxx \ diff --git a/direct/src/plugin/fileSpec.cxx b/direct/src/plugin/fileSpec.cxx index 906fb3acbf..05dc143f9a 100755 --- a/direct/src/plugin/fileSpec.cxx +++ b/direct/src/plugin/fileSpec.cxx @@ -94,33 +94,33 @@ quick_verify(const string &package_dir) const { string pathname = get_pathname(package_dir); struct stat st; if (stat(pathname.c_str(), &st) != 0) { - //nout << "file not found: " << _filename << "\n"; + //cerr << "file not found: " << _filename << "\n"; return false; } if (st.st_size != _size) { // If the size is wrong, the file fails. - //nout << "size wrong: " << _filename << "\n"; + //cerr << "size wrong: " << _filename << "\n"; return false; } if (st.st_mtime == _timestamp) { // If the size is right and the timestamp is right, the file passes. - //nout << "file ok: " << _filename << "\n"; + //cerr << "file ok: " << _filename << "\n"; return true; } - //nout << "modification time wrong: " << _filename << "\n"; + //cerr << "modification time wrong: " << _filename << "\n"; // If the size is right but the timestamp is wrong, the file // soft-fails. We follow this up with a hash check. if (!check_hash(pathname)) { // Hard fail, the hash is wrong. - //nout << "hash check wrong: " << _filename << "\n"; + //cerr << "hash check wrong: " << _filename << "\n"; return false; } - //nout << "hash check ok: " << _filename << "\n"; + //cerr << "hash check ok: " << _filename << "\n"; // The hash is OK after all. Change the file's timestamp back to // what we expect it to be, so we can quick-verify it successfully @@ -149,13 +149,13 @@ full_verify(const string &package_dir) const { string pathname = get_pathname(package_dir); struct stat st; if (stat(pathname.c_str(), &st) != 0) { - //nout << "file not found: " << _filename << "\n"; + //cerr << "file not found: " << _filename << "\n"; return false; } if (st.st_size != _size) { // If the size is wrong, the file fails. - //nout << "size wrong: " << _filename << "\n"; + //cerr << "size wrong: " << _filename << "\n"; return false; } @@ -163,11 +163,11 @@ full_verify(const string &package_dir) const { // soft-fails. We follow this up with a hash check. if (!check_hash(pathname)) { // Hard fail, the hash is wrong. - //nout << "hash check wrong: " << _filename << "\n"; + //cerr << "hash check wrong: " << _filename << "\n"; return false; } - //nout << "hash check ok: " << _filename << "\n"; + //cerr << "hash check ok: " << _filename << "\n"; // The hash is OK. If the timestamp is wrong, change it back to // what we expect it to be, so we can quick-verify it successfully @@ -193,7 +193,7 @@ bool FileSpec:: check_hash(const string &pathname) const { ifstream stream(pathname.c_str(), ios::in | ios::binary); if (!stream) { - //nout << "unable to read " << pathname << "\n"; + //cerr << "unable to read " << pathname << "\n"; return false; } diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index 81cf024589..0bda98e824 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -22,7 +22,7 @@ #include "p3dOsxSplashWindow.h" #include "p3dX11SplashWindow.h" #include "p3dObject.h" -#include "p3dToplevelObject.h" +#include "p3dMainObject.h" #include "p3dUndefinedObject.h" #include "p3dMultifileReader.h" #include "p3dTemporaryFile.h" @@ -57,7 +57,7 @@ P3DInstance(P3D_request_ready_func *func, _func(func) { _browser_script_object = NULL; - _panda_script_object = new P3DToplevelObject; + _panda_script_object = new P3DMainObject; _user_data = user_data; _request_pending = false; _temp_p3d_filename = NULL; @@ -1011,7 +1011,7 @@ handle_notify_request(const string &message) { // to this instance. nout << "Got notify: " << message << "\n"; if (message == "onpythonload") { - // Once Python is up and running, we can get the actual toplevel + // Once Python is up and running, we can get the actual main // object from the Python side, and merge it with our own. TiXmlDocument *doc = new TiXmlDocument; diff --git a/direct/src/plugin/p3dInstance.h b/direct/src/plugin/p3dInstance.h index c8e6b44854..93a5ad0fea 100644 --- a/direct/src/plugin/p3dInstance.h +++ b/direct/src/plugin/p3dInstance.h @@ -39,7 +39,7 @@ class P3DSplashWindow; class P3DDownload; class P3DPackage; class P3DObject; -class P3DToplevelObject; +class P3DMainObject; class P3DTemporaryFile; //////////////////////////////////////////////////////////////////// @@ -144,7 +144,7 @@ private: P3D_request_ready_func *_func; P3D_object *_browser_script_object; - P3DToplevelObject *_panda_script_object; + P3DMainObject *_panda_script_object; P3DTemporaryFile *_temp_p3d_filename; P3DTemporaryFile *_temp_splash_image; diff --git a/direct/src/plugin/p3dInstanceManager.cxx b/direct/src/plugin/p3dInstanceManager.cxx index 2533128f9a..0374f9625f 100644 --- a/direct/src/plugin/p3dInstanceManager.cxx +++ b/direct/src/plugin/p3dInstanceManager.cxx @@ -49,7 +49,7 @@ P3DInstanceManager *P3DInstanceManager::_global_ptr; P3DInstanceManager:: P3DInstanceManager() { _is_initialized = false; - _next_temp_filename_counter = 0; + _next_temp_filename_counter = 1; _unique_id = 0; _notify_thread_continue = false; diff --git a/direct/src/plugin/p3dToplevelObject.cxx b/direct/src/plugin/p3dMainObject.cxx similarity index 86% rename from direct/src/plugin/p3dToplevelObject.cxx rename to direct/src/plugin/p3dMainObject.cxx index e1fb79905d..8d5fa19512 100644 --- a/direct/src/plugin/p3dToplevelObject.cxx +++ b/direct/src/plugin/p3dMainObject.cxx @@ -1,4 +1,4 @@ -// Filename: p3dToplevelObject.cxx +// Filename: p3dMainObject.cxx // Created by: drose (10Jul09) // //////////////////////////////////////////////////////////////////// @@ -12,26 +12,26 @@ // //////////////////////////////////////////////////////////////////// -#include "p3dToplevelObject.h" +#include "p3dMainObject.h" //////////////////////////////////////////////////////////////////// -// Function: P3DToplevelObject::Constructor +// Function: P3DMainObject::Constructor // Access: Public // Description: //////////////////////////////////////////////////////////////////// -P3DToplevelObject:: -P3DToplevelObject() : +P3DMainObject:: +P3DMainObject() : _pyobj(NULL) { } //////////////////////////////////////////////////////////////////// -// Function: P3DToplevelObject::Destructor +// Function: P3DMainObject::Destructor // Access: Public, Virtual // Description: //////////////////////////////////////////////////////////////////// -P3DToplevelObject:: -~P3DToplevelObject() { +P3DMainObject:: +~P3DMainObject() { set_pyobj(NULL); // Clear the local properties. @@ -44,58 +44,58 @@ P3DToplevelObject:: } //////////////////////////////////////////////////////////////////// -// Function: P3DToplevelObject::get_type +// Function: P3DMainObject::get_type // Access: Public, Virtual // Description: Returns the fundamental type of this kind of object. //////////////////////////////////////////////////////////////////// -P3D_object_type P3DToplevelObject:: +P3D_object_type P3DMainObject:: get_type() { return P3D_OT_object; } //////////////////////////////////////////////////////////////////// -// Function: P3DToplevelObject::get_bool +// Function: P3DMainObject::get_bool // Access: Public, Virtual // Description: Returns the object value coerced to a boolean, if // possible. //////////////////////////////////////////////////////////////////// -bool P3DToplevelObject:: +bool P3DMainObject:: get_bool() { return true; } //////////////////////////////////////////////////////////////////// -// Function: P3DToplevelObject::get_int +// Function: P3DMainObject::get_int // Access: Public, Virtual // Description: Returns the object value coerced to an integer, if // possible. //////////////////////////////////////////////////////////////////// -int P3DToplevelObject:: +int P3DMainObject:: get_int() { return 0; } //////////////////////////////////////////////////////////////////// -// Function: P3DToplevelObject::get_float +// Function: P3DMainObject::get_float // Access: Public, Virtual // Description: Returns the object value coerced to a floating-point // value, if possible. //////////////////////////////////////////////////////////////////// -double P3DToplevelObject:: +double P3DMainObject:: get_float() { return 0.0; } //////////////////////////////////////////////////////////////////// -// Function: P3DToplevelObject::make_string +// Function: P3DMainObject::make_string // Access: Public, Virtual // Description: Fills the indicated C++ string object with the value // of this object coerced to a string. //////////////////////////////////////////////////////////////////// -void P3DToplevelObject:: +void P3DMainObject:: make_string(string &value) { if (_pyobj == NULL) { - value = "P3DToplevelObject"; + value = "P3DMainObject"; } else { int size = P3D_OBJECT_GET_STRING(_pyobj, NULL, 0); char *buffer = new char[size]; @@ -106,13 +106,13 @@ make_string(string &value) { } //////////////////////////////////////////////////////////////////// -// Function: P3DToplevelObject::get_property +// Function: P3DMainObject::get_property // Access: Public, Virtual // Description: Returns the named property element in the object. The // return value is a new-reference P3D_object, or NULL // on error. //////////////////////////////////////////////////////////////////// -P3D_object *P3DToplevelObject:: +P3D_object *P3DMainObject:: get_property(const string &property) { if (_pyobj == NULL) { // Without a pyobj, we just report whatever's been stored locally. @@ -131,13 +131,13 @@ get_property(const string &property) { } //////////////////////////////////////////////////////////////////// -// Function: P3DToplevelObject::set_property +// Function: P3DMainObject::set_property // Access: Public, Virtual // Description: Modifies (or deletes, if value is NULL) the named // property element in the object. Returns true on // success, false on failure. //////////////////////////////////////////////////////////////////// -bool P3DToplevelObject:: +bool P3DMainObject:: set_property(const string &property, P3D_object *value) { // First, we set the property locally. if (value != NULL) { @@ -171,12 +171,12 @@ set_property(const string &property, P3D_object *value) { } //////////////////////////////////////////////////////////////////// -// Function: P3DToplevelObject::has_method +// Function: P3DMainObject::has_method // Access: Public, Virtual // Description: Returns true if the named method exists on this // object, false otherwise. //////////////////////////////////////////////////////////////////// -bool P3DToplevelObject:: +bool P3DMainObject:: has_method(const string &method_name) { if (_pyobj == NULL) { // No methods until we get our pyobj. @@ -187,7 +187,7 @@ has_method(const string &method_name) { } //////////////////////////////////////////////////////////////////// -// Function: P3DToplevelObject::call +// Function: P3DMainObject::call // Access: Public, Virtual // Description: Invokes the named method on the object, passing the // indicated parameters. If the method name is empty, @@ -199,7 +199,7 @@ has_method(const string &method_name) { // value is always NULL, and there is no way to // determine success or failure. //////////////////////////////////////////////////////////////////// -P3D_object *P3DToplevelObject:: +P3D_object *P3DMainObject:: call(const string &method_name, bool needs_response, P3D_object *params[], int num_params) { if (_pyobj == NULL) { @@ -212,28 +212,28 @@ call(const string &method_name, bool needs_response, } //////////////////////////////////////////////////////////////////// -// Function: P3DToplevelObject::output +// Function: P3DMainObject::output // Access: Public, Virtual // Description: Writes a formatted representation of the value to the // indicated string. This is intended for developer // assistance. //////////////////////////////////////////////////////////////////// -void P3DToplevelObject:: +void P3DMainObject:: output(ostream &out) { - out << "P3DToplevelObject"; + out << "P3DMainObject"; } //////////////////////////////////////////////////////////////////// -// Function: P3DToplevelObject::set_pyobj +// Function: P3DMainObject::set_pyobj // Access: Public // Description: Changes the internal pyobj pointer. This is the // P3D_object that references the actual PyObject held // within the child process, corresponding to the true -// toplevel object there. The new object's reference +// main object there. The new object's reference // count is incremented, and the previous object's is // decremented. //////////////////////////////////////////////////////////////////// -void P3DToplevelObject:: +void P3DMainObject:: set_pyobj(P3D_object *pyobj) { if (_pyobj != pyobj) { P3D_OBJECT_XDECREF(_pyobj); @@ -254,12 +254,12 @@ set_pyobj(P3D_object *pyobj) { } //////////////////////////////////////////////////////////////////// -// Function: P3DToplevelObject::get_pyobj +// Function: P3DMainObject::get_pyobj // Access: Public // Description: Returns the internal pyobj pointer, or NULL if it has // not yet been set. //////////////////////////////////////////////////////////////////// -P3D_object *P3DToplevelObject:: +P3D_object *P3DMainObject:: get_pyobj() const { return _pyobj; } diff --git a/direct/src/plugin/p3dToplevelObject.h b/direct/src/plugin/p3dMainObject.h similarity index 79% rename from direct/src/plugin/p3dToplevelObject.h rename to direct/src/plugin/p3dMainObject.h index ee77f16de9..eeb1fde396 100644 --- a/direct/src/plugin/p3dToplevelObject.h +++ b/direct/src/plugin/p3dMainObject.h @@ -1,4 +1,4 @@ -// Filename: p3dToplevelObject.h +// Filename: p3dMainObject.h // Created by: drose (10Jul09) // //////////////////////////////////////////////////////////////////// @@ -12,8 +12,8 @@ // //////////////////////////////////////////////////////////////////// -#ifndef P3DTOPLEVELOBJECT_H -#define P3DTOPLEVELOBJECT_H +#ifndef P3DMAINOBJECT_H +#define P3DMAINOBJECT_H #include "p3d_plugin_common.h" #include "p3dObject.h" @@ -22,10 +22,13 @@ class P3DSession; //////////////////////////////////////////////////////////////////// -// Class : P3DToplevelObject -// Description : This corresponds to the toplevel "Python" object -// owned by a particular instance, as returned by -// P3DInstance::get_panda_script_object(). +// Class : P3DMainObject +// Description : This corresponds to the "main" object exposed by a +// particular instance, as returned by +// P3DInstance::get_panda_script_object(). This object +// corresponds to the appRunner.main object in Python, +// and the document.pluginobject.main object in +// JavaScript. // // This is mostly a wrapper around a P3DPythonObject // pointer, and therefore functions like any other @@ -35,10 +38,10 @@ class P3DSession; // generated directly by the core API (like // downloadProgress and such). //////////////////////////////////////////////////////////////////// -class P3DToplevelObject : public P3DObject { +class P3DMainObject : public P3DObject { public: - P3DToplevelObject(); - virtual ~P3DToplevelObject(); + P3DMainObject(); + virtual ~P3DMainObject(); public: virtual P3D_object_type get_type(); diff --git a/direct/src/plugin/p3dPackage.cxx b/direct/src/plugin/p3dPackage.cxx index 75c9bf3b2f..8a87178f17 100755 --- a/direct/src/plugin/p3dPackage.cxx +++ b/direct/src/plugin/p3dPackage.cxx @@ -330,14 +330,19 @@ got_desc_file(TiXmlDocument *doc, bool freshly_downloaded) { extract = extract->NextSiblingElement("extract"); } - // Verify all of the extracts. + // Verify the uncompressed archive. bool all_extracts_ok = true; + if (!_uncompressed_archive.quick_verify(_package_dir)) { + nout << "File is incorrect: " << _uncompressed_archive.get_filename() << "\n"; + all_extracts_ok = false; + } + + // Verify all of the extracts. Extracts::iterator ci; - for (ci = _extracts.begin(); ci != _extracts.end(); ++ci) { + for (ci = _extracts.begin(); ci != _extracts.end() && all_extracts_ok; ++ci) { if (!(*ci).quick_verify(_package_dir)) { nout << "File is incorrect: " << (*ci).get_filename() << "\n"; all_extracts_ok = false; - break; } } diff --git a/direct/src/plugin/p3d_plugin_composite1.cxx b/direct/src/plugin/p3d_plugin_composite1.cxx index 6ce5801458..063489081f 100644 --- a/direct/src/plugin/p3d_plugin_composite1.cxx +++ b/direct/src/plugin/p3d_plugin_composite1.cxx @@ -22,7 +22,7 @@ #include "p3dSplashWindow.cxx" #include "p3dStringObject.cxx" #include "p3dTemporaryFile.cxx" -#include "p3dToplevelObject.cxx" +#include "p3dMainObject.cxx" #include "p3dUndefinedObject.cxx" #include "p3dWinSplashWindow.cxx" #include "p3dX11SplashWindow.cxx" diff --git a/direct/src/plugin_npapi/Sources.pp b/direct/src/plugin_npapi/Sources.pp index 35b0098510..35b72ad611 100644 --- a/direct/src/plugin_npapi/Sources.pp +++ b/direct/src/plugin_npapi/Sources.pp @@ -21,6 +21,7 @@ ppDownloadRequest.h ppDownloadRequest.I \ ppInstance.h ppInstance.I \ ppPandaObject.h ppPandaObject.I \ + ppToplevelObject.h ppToplevelObject.I \ startup.h #define INCLUDED_SOURCES \ @@ -28,6 +29,7 @@ ppDownloadRequest.cxx \ ppInstance.cxx \ ppPandaObject.cxx \ + ppToplevelObject.cxx \ startup.cxx // Windows-specific options. diff --git a/direct/src/plugin_npapi/nppanda3d_composite1.cxx b/direct/src/plugin_npapi/nppanda3d_composite1.cxx index bcb17da76f..3bde838995 100644 --- a/direct/src/plugin_npapi/nppanda3d_composite1.cxx +++ b/direct/src/plugin_npapi/nppanda3d_composite1.cxx @@ -2,6 +2,7 @@ #include "ppDownloadRequest.cxx" #include "ppInstance.cxx" #include "ppPandaObject.cxx" +#include "ppToplevelObject.cxx" #include "startup.cxx" diff --git a/direct/src/plugin_npapi/ppDownloadRequest.h b/direct/src/plugin_npapi/ppDownloadRequest.h index 9b485b9d13..ee2fb1f515 100644 --- a/direct/src/plugin_npapi/ppDownloadRequest.h +++ b/direct/src/plugin_npapi/ppDownloadRequest.h @@ -28,7 +28,8 @@ public: enum RequestType { RT_contents_file, RT_core_dll, - RT_user + RT_user, + RT_instance_data }; inline PPDownloadRequest(RequestType rtype, int user_id = 0); diff --git a/direct/src/plugin_npapi/ppInstance.cxx b/direct/src/plugin_npapi/ppInstance.cxx index 01564a4ded..19883e3aa5 100644 --- a/direct/src/plugin_npapi/ppInstance.cxx +++ b/direct/src/plugin_npapi/ppInstance.cxx @@ -14,6 +14,7 @@ #include "ppInstance.h" #include "ppPandaObject.h" +#include "ppToplevelObject.h" #include "ppBrowserObject.h" #include "startup.h" #include "p3d_plugin_config.h" @@ -73,7 +74,6 @@ PPInstance(NPMIMEType pluginType, NPP instance, uint16 mode, //////////////////////////////////////////////////////////////////// PPInstance:: ~PPInstance() { - nout << "Destructing PPInstance\n"; cleanup_window(); if (_p3d_inst != NULL) { @@ -187,7 +187,17 @@ new_stream(NPMIMEType type, NPStream *stream, bool seekable, uint16 *stype) { _instance_url = stream->url; if (_p3d_inst != NULL) { P3D_instance_start(_p3d_inst, false, _instance_url.c_str()); - } + } + + // We don't want the rest of this stream any more, but we can't + // just return NPERR_GENERIC_ERROR, though--that seems to freak + // out Mozilla. Instead, we'll "accept" it for now, and then + // immediately stop it when we get the first write_stream() + // call. + stream->notifyData = new PPDownloadRequest(PPDownloadRequest::RT_instance_data); + + *stype = NP_NORMAL; + return NPERR_NO_ERROR; } // Don't finish downloading the unsolicited stream. @@ -232,6 +242,7 @@ int PPInstance:: write_stream(NPStream *stream, int offset, int len, void *buffer) { if (stream->notifyData == NULL) { nout << "Unexpected write_stream on " << stream->url << "\n"; + browser->destroystream(_npp_instance, stream, NPRES_USER_BREAK); return 0; } @@ -242,12 +253,18 @@ write_stream(NPStream *stream, int offset, int len, void *buffer) { P3D_RC_in_progress, 0, stream->end, buffer, len); return len; + + case PPDownloadRequest::RT_instance_data: + // Here's a stream we don't really want. + browser->destroystream(_npp_instance, stream, NPRES_USER_BREAK); + return 0; default: nout << "Unexpected write_stream on " << stream->url << "\n"; break; } + browser->destroystream(_npp_instance, stream, NPRES_USER_BREAK); return 0; } @@ -262,7 +279,7 @@ NPError PPInstance:: destroy_stream(NPStream *stream, NPReason reason) { if (stream->notifyData == NULL) { nout << "Unexpected destroy_stream on " << stream->url << "\n"; - return NPERR_GENERIC_ERROR; + return NPERR_NO_ERROR; } PPDownloadRequest *req = (PPDownloadRequest *)(stream->notifyData); @@ -280,10 +297,16 @@ destroy_stream(NPStream *stream, NPReason reason) { } break; + case PPDownloadRequest::RT_instance_data: + // We won't get a url_notify on this one, so delete it now. + delete req; + break; + default: + nout << "Unexpected destroy_stream on " << stream->url << "\n"; break; } - + return NPERR_NO_ERROR; } @@ -333,6 +356,7 @@ url_notify(const char *url, NPReason reason, void *notifyData) { break; default: + nout << "Unexpected url_notify on stream type " << req->_rtype << "\n"; break; } @@ -539,13 +563,14 @@ get_panda_script_object() { return _script_object; } - P3D_object *obj = NULL; + P3D_object *main = NULL; if (_p3d_inst != NULL) { - obj = P3D_instance_get_panda_script_object(_p3d_inst); + main = P3D_instance_get_panda_script_object(_p3d_inst); } - _script_object = PPPandaObject::make_new(this, obj); + _script_object = PPToplevelObject::make_new(this); + _script_object->set_main(main); browser->retainobject(_script_object); return _script_object; @@ -975,8 +1000,8 @@ create_instance() { if (_script_object != NULL) { // Now that we have a true instance, initialize our // script_object with the proper P3D_object pointer. - P3D_object *obj = P3D_instance_get_panda_script_object(_p3d_inst); - _script_object->set_p3d_object(obj); + P3D_object *main = P3D_instance_get_panda_script_object(_p3d_inst); + _script_object->set_main(main); } if (_got_instance_url) { @@ -1069,7 +1094,6 @@ send_window() { // No size: hidden. window_type = P3D_WT_hidden; } - nout << "window_type = " << window_type << "\n"; P3D_instance_setup_window (_p3d_inst, window_type, @@ -1090,7 +1114,6 @@ cleanup_window() { // Restore the parent window to its own window handler. HWND hwnd = (HWND)_window.window; SetWindowLongPtr(hwnd, GWL_WNDPROC, _orig_window_proc); - nout << "Restored window handler for " << hwnd << "\n"; InvalidateRect(hwnd, NULL, true); #endif // _WIN32 _got_window = false; diff --git a/direct/src/plugin_npapi/ppInstance.h b/direct/src/plugin_npapi/ppInstance.h index d02178fcfd..21b44c9ab2 100644 --- a/direct/src/plugin_npapi/ppInstance.h +++ b/direct/src/plugin_npapi/ppInstance.h @@ -22,7 +22,7 @@ #include -class PPPandaObject; +class PPToplevelObject; class PPDownloadRequest; //////////////////////////////////////////////////////////////////// @@ -140,7 +140,7 @@ private: bool _python_window_open; - PPPandaObject *_script_object; + PPToplevelObject *_script_object; P3D_instance *_p3d_inst; }; diff --git a/direct/src/plugin_npapi/ppToplevelObject.I b/direct/src/plugin_npapi/ppToplevelObject.I new file mode 100644 index 0000000000..114b4d28d0 --- /dev/null +++ b/direct/src/plugin_npapi/ppToplevelObject.I @@ -0,0 +1,14 @@ +// Filename: ppToplevelObject.I +// Created by: drose (21Aug09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + diff --git a/direct/src/plugin_npapi/ppToplevelObject.cxx b/direct/src/plugin_npapi/ppToplevelObject.cxx new file mode 100644 index 0000000000..48c386ca5e --- /dev/null +++ b/direct/src/plugin_npapi/ppToplevelObject.cxx @@ -0,0 +1,276 @@ +// Filename: ppToplevelObject.cxx +// Created by: drose (21Aug09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#include "ppToplevelObject.h" + +NPClass PPToplevelObject::_object_class = { + NP_CLASS_STRUCT_VERSION, + &PPToplevelObject::NPAllocate, + &PPToplevelObject::NPDeallocate, + &PPToplevelObject::NPInvalidate, + &PPToplevelObject::NPHasMethod, + &PPToplevelObject::NPInvoke, + &PPToplevelObject::NPInvokeDefault, + &PPToplevelObject::NPHasProperty, + &PPToplevelObject::NPGetProperty, + &PPToplevelObject::NPSetProperty, + &PPToplevelObject::NPRemoveProperty, +#if defined(NP_CLASS_STRUCT_VERSION_ENUM) && NP_CLASS_STRUCT_VERSION >= NP_CLASS_STRUCT_VERSION_ENUM + &PPToplevelObject::NPEnumerate, +#endif +#if defined(NP_CLASS_STRUCT_VERSION_CTOR) && NP_CLASS_STRUCT_VERSION >= NP_CLASS_STRUCT_VERSION_CTOR + &PPToplevelObject::NPConstruct, +#endif +}; + + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::make_new +// Access: Public, Static +// Description: Use this call to construct a new PPToplevelObject. +//////////////////////////////////////////////////////////////////// +PPToplevelObject *PPToplevelObject:: +make_new(PPInstance *inst) { + NPObject *npobj = + browser->createobject(inst->get_npp_instance(), &_object_class); + PPToplevelObject *ppobj = (PPToplevelObject *)npobj; + ppobj->construct(inst); + return ppobj; +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::set_main +// Access: Public +// Description: Changes the "main" object this PPToplevelObject maps +// to. The new object's reference count is incremented, +// and the previous object's is decremented. +//////////////////////////////////////////////////////////////////// +void PPToplevelObject:: +set_main(P3D_object *p3d_object) { + if (p3d_object != NULL) { + P3D_OBJECT_INCREF(p3d_object); + } + P3D_OBJECT_XDECREF(_main); + _main = p3d_object; +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::construct +// Access: Private +// Description: Stands in for the C++ constructor. We can't have a +// true constructor because of the C-style interface in +// NPN_CreateObject(). This must be called explicitly +// following NPN_CreateObject(). +//////////////////////////////////////////////////////////////////// +void PPToplevelObject:: +construct(PPInstance *inst) { + _instance = inst; + _main = NULL; + + // Get our one property name as an identifier, so we can look for + // it. + _main_id = browser->getstringidentifier("main"); +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::invalidate +// Access: Private +// Description: This "destructor" is called by NPInvalidate(). +//////////////////////////////////////////////////////////////////// +void PPToplevelObject:: +invalidate() { + _instance = NULL; + set_main(NULL); +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::has_property +// Access: Private +// Description: Returns true if the object has the named property, +// false otherwise. +//////////////////////////////////////////////////////////////////// +bool PPToplevelObject:: +has_property(NPIdentifier name) { + if (_main == NULL) { + // Not powered up yet. + return false; + } + + if (name == _main_id) { + return true; + } + + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::get_property +// Access: Private +// Description: Retrieves the named property value from the object +// and stores it in result. Returns true on success, +// false on failure. +//////////////////////////////////////////////////////////////////// +bool PPToplevelObject:: +get_property(NPIdentifier name, NPVariant *result) { + if (_main == NULL) { + // Not powered up yet. + return false; + } + + if (name == _main_id) { + _instance->p3dobj_to_variant(result, _main); + return true; + } + + return false; +} + + +// The remaining function bodies are the C-style function wrappers +// that are called directly by NPAPI, and which redirect into the +// above C++-style methods. + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::NPAllocate +// Access: Private, Static +// Description: Called by NPN_CreateObject() to allocate space for +// this object. +//////////////////////////////////////////////////////////////////// +NPObject *PPToplevelObject:: +NPAllocate(NPP npp, NPClass *aClass) { + assert(aClass == &_object_class); + return (PPToplevelObject *)malloc(sizeof(PPToplevelObject)); +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::Deallocate +// Access: Private, Static +// Description: Called to delete the space allocated by NPAllocate, +// above. +//////////////////////////////////////////////////////////////////// +void PPToplevelObject:: +NPDeallocate(NPObject *npobj) { + ((PPToplevelObject *)npobj)->invalidate(); + free(npobj); +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::Deallocate +// Access: Private, Static +// Description: Called to destruct the object. +//////////////////////////////////////////////////////////////////// +void PPToplevelObject:: +NPInvalidate(NPObject *npobj) { + // It turns out that this method isn't actually called by Safari's + // implementation of NPAPI, so we'll move the actual destructor call + // into NPDeallocate, above. +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::NPHasMethod +// Access: Private, Static +// Description: +//////////////////////////////////////////////////////////////////// +bool PPToplevelObject:: +NPHasMethod(NPObject *npobj, NPIdentifier name) { + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::NPInvoke +// Access: Private, Static +// Description: +//////////////////////////////////////////////////////////////////// +bool PPToplevelObject:: +NPInvoke(NPObject *npobj, NPIdentifier name, + const NPVariant *args, uint32_t argCount, + NPVariant *result) { + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::NPInvokeDefault +// Access: Private, Static +// Description: +//////////////////////////////////////////////////////////////////// +bool PPToplevelObject:: +NPInvokeDefault(NPObject *npobj, const NPVariant *args, uint32_t argCount, + NPVariant *result) { + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::NPHasProperty +// Access: Private, Static +// Description: +//////////////////////////////////////////////////////////////////// +bool PPToplevelObject:: +NPHasProperty(NPObject *npobj, NPIdentifier name) { + return ((PPToplevelObject *)npobj)->has_property(name); +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::NPGetProperty +// Access: Private, Static +// Description: +//////////////////////////////////////////////////////////////////// +bool PPToplevelObject:: +NPGetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result) { + return ((PPToplevelObject *)npobj)->get_property(name, result); +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::NPSetProperty +// Access: Private, Static +// Description: +//////////////////////////////////////////////////////////////////// +bool PPToplevelObject:: +NPSetProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value) { + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::NPRemoveProperty +// Access: Private, Static +// Description: +//////////////////////////////////////////////////////////////////// +bool PPToplevelObject:: +NPRemoveProperty(NPObject *npobj, NPIdentifier name) { + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::NPEnumerate +// Access: Private, Static +// Description: +//////////////////////////////////////////////////////////////////// +bool PPToplevelObject:: +NPEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count) { + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: PPToplevelObject::NPConstruct +// Access: Private, Static +// Description: +//////////////////////////////////////////////////////////////////// +bool PPToplevelObject:: +NPConstruct(NPObject *npobj, const NPVariant *args, + uint32_t argCount, NPVariant *result) { + // Not implemented. We don't use this constructor mechanism because + // it wasn't supported on earlier versions of Gecko. Instead, we + // use make_new() to construct PPToplevelObjects via an explicit call to + // construct(). + return true; +} diff --git a/direct/src/plugin_npapi/ppToplevelObject.h b/direct/src/plugin_npapi/ppToplevelObject.h new file mode 100644 index 0000000000..a1b291ff95 --- /dev/null +++ b/direct/src/plugin_npapi/ppToplevelObject.h @@ -0,0 +1,80 @@ +// Filename: ppToplevelObject.h +// Created by: drose (21Aug09) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) Carnegie Mellon University. All rights reserved. +// +// All use of this software is subject to the terms of the revised BSD +// license. You should have received a copy of this license along +// with this source code in a file named "LICENSE." +// +//////////////////////////////////////////////////////////////////// + +#ifndef PPTOPLEVELOBJECT_H +#define PPTOPLEVELOBJECT_H + +#include "nppanda3d_common.h" + +//////////////////////////////////////////////////////////////////// +// Class : PPToplevelObject +// Description : This is a special object fed to Mozilla as the +// toplevel scripting object for the instance. It has +// only one property, "main", which corresponds to the +// appRunner.main object from Python. +//////////////////////////////////////////////////////////////////// +class PPToplevelObject : public NPObject { +public: + static PPToplevelObject *make_new(PPInstance *inst); + + inline P3D_object *get_main() const; + void set_main(P3D_object *main); + +private: + void construct(PPInstance *inst); + void invalidate(); + + bool has_property(NPIdentifier name); + bool get_property(NPIdentifier name, + NPVariant *result); + +private: + static NPObject *NPAllocate(NPP npp, NPClass *aClass); + static void NPDeallocate(NPObject *npobj); + static void NPInvalidate(NPObject *npobj); + static bool NPHasMethod(NPObject *npobj, NPIdentifier name); + static bool NPInvoke(NPObject *npobj, NPIdentifier name, + const NPVariant *args, uint32_t argCount, + NPVariant *result); + static bool NPInvokeDefault(NPObject *npobj, + const NPVariant *args, + uint32_t argCount, + NPVariant *result); + static bool NPHasProperty(NPObject *npobj, NPIdentifier name); + static bool NPGetProperty(NPObject *npobj, NPIdentifier name, + NPVariant *result); + static bool NPSetProperty(NPObject *npobj, NPIdentifier name, + const NPVariant *value); + static bool NPRemoveProperty(NPObject *npobj, + NPIdentifier name); + static bool NPEnumerate(NPObject *npobj, NPIdentifier **value, + uint32_t *count); + static bool NPConstruct(NPObject *npobj, + const NPVariant *args, + uint32_t argCount, + NPVariant *result); + +private: + PPInstance *_instance; + P3D_object *_main; + NPIdentifier _main_id; + +public: + static NPClass _object_class; +}; + +#include "ppToplevelObject.I" + +#endif +