From a308a4a01c66cc00881c8b0a8ef9252fa74a2d52 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 6 Oct 2009 18:55:28 +0000 Subject: [PATCH] add p3dpythonw.exe, more robust startup --- direct/src/p3d/Packager.py | 2 + direct/src/plugin/Sources.pp | 46 ++++++++++++ direct/src/plugin/load_plugin.cxx | 4 +- direct/src/plugin/load_plugin.h | 2 +- direct/src/plugin/p3dInstance.cxx | 49 +++++++++++-- direct/src/plugin/p3dInstance.h | 3 +- direct/src/plugin/p3dInstanceManager.I | 20 +++++- direct/src/plugin/p3dInstanceManager.cxx | 4 +- direct/src/plugin/p3dInstanceManager.h | 5 +- direct/src/plugin/p3dMainObject.cxx | 6 +- direct/src/plugin/p3dMainObject.h | 3 +- direct/src/plugin/p3dObject.cxx | 28 ++++---- direct/src/plugin/p3dObject.h | 11 +-- direct/src/plugin/p3dPythonMain.cxx | 70 +++++++++++++++++++ direct/src/plugin/p3dPythonObject.cxx | 8 +-- direct/src/plugin/p3dPythonObject.h | 2 +- direct/src/plugin/p3dSession.cxx | 19 +++-- direct/src/plugin/p3dWinSplashWindow.cxx | 9 ++- direct/src/plugin/p3d_plugin.cxx | 8 +-- direct/src/plugin/p3d_plugin.h | 33 +++++---- direct/src/plugin_activex/PPBrowserObject.cpp | 7 +- direct/src/plugin_activex/PPBrowserObject.h | 3 +- direct/src/plugin_activex/PPInstance.cpp | 2 +- direct/src/plugin_activex/PPInterface.cpp | 6 +- direct/src/plugin_activex/PPPandaObject.cpp | 1 + direct/src/plugin_npapi/ppBrowserObject.cxx | 6 +- direct/src/plugin_npapi/ppBrowserObject.h | 3 +- direct/src/plugin_npapi/ppInstance.cxx | 2 +- direct/src/plugin_npapi/ppPandaObject.cxx | 6 +- direct/src/plugin_standalone/panda3d.cxx | 18 ++--- 30 files changed, 296 insertions(+), 90 deletions(-) diff --git a/direct/src/p3d/Packager.py b/direct/src/p3d/Packager.py index 609e4dfa5c..775eed7b14 100644 --- a/direct/src/p3d/Packager.py +++ b/direct/src/p3d/Packager.py @@ -2411,6 +2411,8 @@ class Packager: # extensions are automatically replaced with the appropriate # platform-specific extensions. self.do_file('p3dpython.exe') + if PandaSystem.getPlatform().startswith('win'): + self.do_file('p3dpythonw.exe') self.do_file('libp3dpython.dll') def do_freeze(self, filename, compileToExe = False): diff --git a/direct/src/plugin/Sources.pp b/direct/src/plugin/Sources.pp index 19b8e4fc0a..49697b0966 100644 --- a/direct/src/plugin/Sources.pp +++ b/direct/src/plugin/Sources.pp @@ -183,6 +183,52 @@ #define WIN_SYS_LIBS user32.lib #end bin_target +#begin bin_target + // Windows requires a special executable, p3dpythonw.exe, to launch + // a desktop-friendly application. + #define BUILD_TARGET $[and $[HAVE_TINYXML],$[HAVE_PYTHON],$[HAVE_OPENSSL],$[WINDOWS_PLATFORM]] + #define USE_PACKAGES tinyxml python openssl + #define TARGET p3dpythonw + #define EXTRA_CDEFS NON_CONSOLE + + #define OTHER_LIBS \ + dtoolutil:c dtoolbase:c dtool:m \ + interrogatedb:c dconfig:c dtoolconfig:m \ + express:c pandaexpress:m \ + pgraph:c pgraphnodes:c cull:c gsgbase:c gobj:c \ + mathutil:c lerp:c downloader:c pnmimage:c \ + prc:c pstatclient:c pandabase:c linmath:c putil:c \ + pipeline:c event:c nativenet:c net:c display:c panda:m + + #define SOURCES \ + binaryXml.cxx binaryXml.h \ + fhandle.h \ + handleStream.cxx handleStream.h handleStream.I \ + handleStreamBuf.cxx handleStreamBuf.h handleStreamBuf.I \ + p3d_lock.h p3d_plugin.h \ + p3d_plugin_config.h \ + p3dCInstance.cxx \ + p3dCInstance.h p3dCInstance.I \ + p3dPythonRun.cxx p3dPythonRun.h p3dPythonRun.I \ + run_p3dpython.h run_p3dpython.cxx + + #define SOURCES $[SOURCES] \ + p3dPythonMain.cxx + + // If you have to link with a static Python library, define it here. + #define EXTRA_LIBS $[EXTRA_P3DPYTHON_LIBS] + #define OSX_SYS_FRAMEWORKS Carbon + + #if $[OSX_PLATFORM] + // Not entirely sure why this option is required for OSX, but we + // get objections about ___dso_handle otherwise--but only when + // building universal binaries. + #define LFLAGS $[LFLAGS] -undefined dynamic_lookup + #endif + + #define WIN_SYS_LIBS user32.lib +#end bin_target + #begin static_lib_target #define BUILD_TARGET $[and $[HAVE_TINYXML],$[HAVE_OPENSSL]] #define TARGET plugin_common diff --git a/direct/src/plugin/load_plugin.cxx b/direct/src/plugin/load_plugin.cxx index 0f61c045ad..f390f23fdb 100755 --- a/direct/src/plugin/load_plugin.cxx +++ b/direct/src/plugin/load_plugin.cxx @@ -128,7 +128,7 @@ load_plugin(const string &p3d_plugin_filename, const string &contents_filename, const string &download_url, bool verify_contents, const string &platform, const string &log_directory, const string &log_basename, - bool trusted_environment, + bool trusted_environment, bool console_environment, ostream &logfile) { string filename = p3d_plugin_filename; if (filename.empty()) { @@ -313,7 +313,7 @@ load_plugin(const string &p3d_plugin_filename, if (!P3D_initialize(P3D_API_VERSION, contents_filename.c_str(), download_url.c_str(), verify_contents, platform.c_str(), log_directory.c_str(), log_basename.c_str(), - trusted_environment)) { + trusted_environment, console_environment)) { // Oops, failure to initialize. logfile << "Failed to initialize plugin (wrong API version?)\n"; unload_plugin(); diff --git a/direct/src/plugin/load_plugin.h b/direct/src/plugin/load_plugin.h index 1bcfb417da..29d225f045 100755 --- a/direct/src/plugin/load_plugin.h +++ b/direct/src/plugin/load_plugin.h @@ -64,7 +64,7 @@ load_plugin(const string &p3d_plugin_filename, const string &contents_filename, const string &download_url, bool verify_contents, const string &platform, const string &log_directory, const string &log_basename, - bool trusted_environment, + bool trusted_environment, bool console_environment, ostream &logfile); void unload_plugin(); bool is_plugin_loaded(); diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index b7d7b575ab..3855e4158d 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -864,15 +864,54 @@ start_download(P3DDownload *download) { } //////////////////////////////////////////////////////////////////// -// Function: P3DInstance::request_stop +// Function: P3DInstance::request_stop_sub_thread // Access: Public // Description: Asks the host to shut down this particular instance, // presumably because the user has indicated it should -// exit. +// exit. This call may be made in any thread. //////////////////////////////////////////////////////////////////// void P3DInstance:: -request_stop() { +request_stop_sub_thread() { + // Atomically check _requested_stop. + bool add_request = false; + ACQUIRE_LOCK(_request_lock); if (!_requested_stop) { + _requested_stop = true; + add_request = true; + } + RELEASE_LOCK(_request_lock); + + // If we haven't requested a stop already, do it now. + if (add_request) { + TiXmlDocument *doc = new TiXmlDocument; + TiXmlElement *xrequest = new TiXmlElement("request"); + xrequest->SetAttribute("rtype", "stop"); + doc->LinkEndChild(xrequest); + + add_raw_request(doc); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DInstance::request_stop_main_thread +// Access: Public +// Description: Asks the host to shut down this particular instance, +// presumably because the user has indicated it should +// exit. This call may only be made in the main thread. +//////////////////////////////////////////////////////////////////// +void P3DInstance:: +request_stop_main_thread() { + // Atomically check _requested_stop. + bool add_request = false; + ACQUIRE_LOCK(_request_lock); + if (!_requested_stop) { + _requested_stop = true; + add_request = true; + } + RELEASE_LOCK(_request_lock); + + // If we haven't requested a stop already, do it now. + if (add_request) { _requested_stop = true; P3D_request *request = new P3D_request; request->_request_type = P3D_RT_stop; @@ -1533,7 +1572,7 @@ handle_script_request(const string &operation, P3D_object *object, } else if (operation == "set_property") { bool result = - P3D_OBJECT_SET_PROPERTY(object, property_name.c_str(), value); + P3D_OBJECT_SET_PROPERTY(object, property_name.c_str(), true, value); TiXmlElement *xvalue = new TiXmlElement("value"); xvalue->SetAttribute("type", "bool"); @@ -1541,7 +1580,7 @@ handle_script_request(const string &operation, P3D_object *object, xcommand->LinkEndChild(xvalue); } else if (operation == "del_property") { - bool result = P3D_OBJECT_SET_PROPERTY(object, property_name.c_str(), NULL); + bool result = P3D_OBJECT_SET_PROPERTY(object, property_name.c_str(), true, NULL); TiXmlElement *xvalue = new TiXmlElement("value"); xvalue->SetAttribute("type", "bool"); diff --git a/direct/src/plugin/p3dInstance.h b/direct/src/plugin/p3dInstance.h index 0f5effaec9..17b090270b 100644 --- a/direct/src/plugin/p3dInstance.h +++ b/direct/src/plugin/p3dInstance.h @@ -98,7 +98,8 @@ public: inline bool is_trusted() const; void start_download(P3DDownload *download); inline bool is_started() const; - void request_stop(); + void request_stop_sub_thread(); + void request_stop_main_thread(); void request_refresh(); TiXmlElement *make_xml(); diff --git a/direct/src/plugin/p3dInstanceManager.I b/direct/src/plugin/p3dInstanceManager.I index 4aae0aadb7..a295325d54 100644 --- a/direct/src/plugin/p3dInstanceManager.I +++ b/direct/src/plugin/p3dInstanceManager.I @@ -127,13 +127,31 @@ get_log_pathname() const { // file will be run without checking its signature. // // This should generally be true only when run by -// panda3d.exe, and not when run by the web plugin. +// panda3d.exe or panda3dw.exe, and not when run by the +// web plugin. //////////////////////////////////////////////////////////////////// inline bool P3DInstanceManager:: get_trusted_environment() const { return _trusted_environment; } +//////////////////////////////////////////////////////////////////// +// Function: P3DInstanceManager::get_console_environment +// Access: Public +// Description: Returns the value of the console_environment flag +// passed to the constructor. If this is true, it means +// we are running from a text-based console window, and +// not from a desktop environment. +// +// This should generally be true only when run by +// panda3d.exe, and not when run by the web plugin or by +// panda3dw.exe. +//////////////////////////////////////////////////////////////////// +inline bool P3DInstanceManager:: +get_console_environment() const { + return _console_environment; +} + //////////////////////////////////////////////////////////////////// // Function: P3DInstanceManager::get_super_mirror // Access: Public diff --git a/direct/src/plugin/p3dInstanceManager.cxx b/direct/src/plugin/p3dInstanceManager.cxx index 9db9b4a909..42baf33918 100644 --- a/direct/src/plugin/p3dInstanceManager.cxx +++ b/direct/src/plugin/p3dInstanceManager.cxx @@ -172,8 +172,10 @@ bool P3DInstanceManager:: initialize(const string &contents_filename, const string &download_url, bool verify_contents, const string &platform, const string &log_directory, - const string &log_basename, bool trusted_environment) { + const string &log_basename, bool trusted_environment, + bool console_environment) { _trusted_environment = trusted_environment; + _console_environment = console_environment; _verify_contents = verify_contents; _platform = platform; if (_platform.empty()) { diff --git a/direct/src/plugin/p3dInstanceManager.h b/direct/src/plugin/p3dInstanceManager.h index ff87059b4f..1b03c65071 100644 --- a/direct/src/plugin/p3dInstanceManager.h +++ b/direct/src/plugin/p3dInstanceManager.h @@ -55,7 +55,8 @@ public: const string &platform, const string &log_directory, const string &log_basename, - bool trusted_environment); + bool trusted_environment, + bool console_environment); inline bool is_initialized() const; inline bool get_verify_contents() const; @@ -67,6 +68,7 @@ public: inline const string &get_log_directory() const; inline const string &get_log_pathname() const; inline bool get_trusted_environment() const; + inline bool get_console_environment() const; void set_super_mirror(const string &super_mirror_url); inline const string &get_super_mirror() const; @@ -133,6 +135,7 @@ private: string _log_pathname; string _temp_directory; bool _trusted_environment; + bool _console_environment; string _super_mirror_url; P3D_object *_undefined_object; diff --git a/direct/src/plugin/p3dMainObject.cxx b/direct/src/plugin/p3dMainObject.cxx index 51d28a11ec..b9e7e82996 100644 --- a/direct/src/plugin/p3dMainObject.cxx +++ b/direct/src/plugin/p3dMainObject.cxx @@ -143,7 +143,7 @@ get_property(const string &property) { // success, false on failure. //////////////////////////////////////////////////////////////////// bool P3DMainObject:: -set_property(const string &property, P3D_object *value) { +set_property(const string &property, bool needs_response, P3D_object *value) { // First, we set the property locally. if (value != NULL) { Properties::iterator pi; @@ -172,7 +172,7 @@ set_property(const string &property, P3D_object *value) { } // With a pyobj, we also pass this request down. - return P3D_OBJECT_SET_PROPERTY(_pyobj, property.c_str(), value); + return P3D_OBJECT_SET_PROPERTY(_pyobj, property.c_str(), needs_response, value); } //////////////////////////////////////////////////////////////////// @@ -269,7 +269,7 @@ set_pyobj(P3D_object *pyobj) { for (pi = _properties.begin(); pi != _properties.end(); ++pi) { const string &property_name = (*pi).first; P3D_object *value = (*pi).second; - P3D_OBJECT_SET_PROPERTY(_pyobj, property_name.c_str(), value); + P3D_OBJECT_SET_PROPERTY(_pyobj, property_name.c_str(), false, value); } } } diff --git a/direct/src/plugin/p3dMainObject.h b/direct/src/plugin/p3dMainObject.h index 860078c140..9d9cc1e8af 100644 --- a/direct/src/plugin/p3dMainObject.h +++ b/direct/src/plugin/p3dMainObject.h @@ -53,7 +53,8 @@ public: virtual void make_string(string &value); virtual P3D_object *get_property(const string &property); - virtual bool set_property(const string &property, P3D_object *value); + virtual bool set_property(const string &property, bool needs_response, + P3D_object *value); virtual bool has_method(const string &method_name); virtual P3D_object *call(const string &method_name, bool needs_response, diff --git a/direct/src/plugin/p3dObject.cxx b/direct/src/plugin/p3dObject.cxx index c151daad84..b0e9f7331a 100644 --- a/direct/src/plugin/p3dObject.cxx +++ b/direct/src/plugin/p3dObject.cxx @@ -65,8 +65,8 @@ object_get_property(P3D_object *object, const char *property) { static bool object_set_property(P3D_object *object, const char *property, - P3D_object *value) { - return ((P3DObject *)object)->set_property(property, value); + bool needs_response, P3D_object *value) { + return ((P3DObject *)object)->set_property(property, needs_response, value); } static bool @@ -155,7 +155,7 @@ generic_get_property(P3D_object *object, const char *property) { static bool generic_set_property(P3D_object *object, const char *property, - P3D_object *value) { + bool needs_response, P3D_object *value) { return false; } @@ -275,7 +275,7 @@ get_property(const string &property) { // success, false on failure. //////////////////////////////////////////////////////////////////// bool P3DObject:: -set_property(const string &property, P3D_object *value) { +set_property(const string &property, bool needs_response, P3D_object *value) { return false; } @@ -398,12 +398,11 @@ get_bool_property(const string &property) { // Description: Changes the value of the named property to the // indicated boolean value. //////////////////////////////////////////////////////////////////// -bool P3DObject:: +void P3DObject:: set_bool_property(const string &property, bool value) { P3D_object *bvalue = new P3DBoolObject(value); - bool result = set_property(property, bvalue); + set_property(property, false, bvalue); P3D_OBJECT_DECREF(bvalue); - return result; } //////////////////////////////////////////////////////////////////// @@ -429,12 +428,11 @@ get_int_property(const string &property) { // Description: Changes the value of the named property to the // indicated integer value. //////////////////////////////////////////////////////////////////// -bool P3DObject:: +void P3DObject:: set_int_property(const string &property, int value) { P3D_object *ivalue = new P3DIntObject(value); - bool result = set_property(property, ivalue); + set_property(property, false, ivalue); P3D_OBJECT_DECREF(ivalue); - return result; } //////////////////////////////////////////////////////////////////// @@ -461,12 +459,11 @@ get_float_property(const string &property) { // Description: Changes the value of the named property to the // indicated floating-point value. //////////////////////////////////////////////////////////////////// -bool P3DObject:: +void P3DObject:: set_float_property(const string &property, double value) { P3D_object *fvalue = new P3DFloatObject(value); - bool result = set_property(property, fvalue); + set_property(property, false, fvalue); P3D_OBJECT_DECREF(fvalue); - return result; } //////////////////////////////////////////////////////////////////// @@ -499,10 +496,9 @@ get_string_property(const string &property) { // Description: Changes the value of the named property to the // indicated string value. //////////////////////////////////////////////////////////////////// -bool P3DObject:: +void P3DObject:: set_string_property(const string &property, const string &value) { P3D_object *svalue = new P3DStringObject(value); - bool result = set_property(property, svalue); + set_property(property, false, svalue); P3D_OBJECT_DECREF(svalue); - return result; } diff --git a/direct/src/plugin/p3dObject.h b/direct/src/plugin/p3dObject.h index 09a1218346..e252bdab56 100644 --- a/direct/src/plugin/p3dObject.h +++ b/direct/src/plugin/p3dObject.h @@ -43,7 +43,8 @@ public: virtual void make_string(string &value)=0; virtual P3D_object *get_property(const string &property); - virtual bool set_property(const string &property, P3D_object *value); + virtual bool set_property(const string &property, bool needs_response, + P3D_object *value); virtual bool has_method(const string &method_name); virtual P3D_object *call(const string &method_name, bool needs_response, @@ -57,16 +58,16 @@ public: // Convenience functions. bool get_bool_property(const string &property); - bool set_bool_property(const string &property, bool value); + void set_bool_property(const string &property, bool value); int get_int_property(const string &property); - bool set_int_property(const string &property, int value); + void set_int_property(const string &property, int value); double get_float_property(const string &property); - bool set_float_property(const string &property, double value); + void set_float_property(const string &property, double value); string get_string_property(const string &property); - bool set_string_property(const string &property, const string &value); + void set_string_property(const string &property, const string &value); public: static P3D_class_definition _object_class; diff --git a/direct/src/plugin/p3dPythonMain.cxx b/direct/src/plugin/p3dPythonMain.cxx index fd26a17dc0..347e6f56fb 100644 --- a/direct/src/plugin/p3dPythonMain.cxx +++ b/direct/src/plugin/p3dPythonMain.cxx @@ -16,6 +16,8 @@ #include #include +#include +#include #include // strrchr using namespace std; @@ -24,6 +26,74 @@ using namespace std; extern "C" { void CPSEnableForegroundOperation(ProcessSerialNumber* psn); } #endif +#if defined(_WIN32) && defined(NON_CONSOLE) +// On Windows, we may need to build p3dpythonw.exe, a non-console +// version of this program. + +// We'll wrap the main() function with our own startup WinMain(). +#define main local_main +int main(int argc, char *argv[]); + +// Returns a newly-allocated string representing the quoted argument +// beginning at p. Advances p to the first character following the +// close quote. +static char * +parse_quoted_arg(char *&p) { + char quote = *p; + ++p; + string result; + + while (*p != '\0' && *p != quote) { + // TODO: handle escape characters? Not sure if we need to. + result += *p; + ++p; + } + if (*p == quote) { + ++p; + } + return strdup(result.c_str()); +} + +// Returns a newly-allocated string representing the unquoted argument +// beginning at p. Advances p to the first whitespace following the +// argument. +static char * +parse_unquoted_arg(char *&p) { + string result; + while (*p != '\0' && !isspace(*p)) { + result += *p; + ++p; + } + return strdup(result.c_str()); +} + +int WINAPI +WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { + char *command_line = GetCommandLine(); + + vector argv; + + char *p = command_line; + while (*p != '\0') { + if (*p == '"') { + char *arg = parse_quoted_arg(p); + argv.push_back(arg); + } else { + char *arg = parse_unquoted_arg(p); + argv.push_back(arg); + } + + // Skip whitespace. + while (*p != '\0' && isspace(*p)) { + ++p; + } + } + + assert(!argv.empty()); + return main(argv.size(), &argv[0]); +} +#endif // NON_CONSOLE + //////////////////////////////////////////////////////////////////// // Function: main // Description: This is a trivial main() function that invokes diff --git a/direct/src/plugin/p3dPythonObject.cxx b/direct/src/plugin/p3dPythonObject.cxx index 638e8a5f77..3c73f6ae05 100644 --- a/direct/src/plugin/p3dPythonObject.cxx +++ b/direct/src/plugin/p3dPythonObject.cxx @@ -153,8 +153,8 @@ get_property(const string &property) { // success, false on failure. //////////////////////////////////////////////////////////////////// bool P3DPythonObject:: -set_property(const string &property, P3D_object *value) { - bool bresult = false; +set_property(const string &property, bool needs_response, P3D_object *value) { + bool bresult = !needs_response; P3D_object *params[2]; params[0] = new P3DStringObject(property); @@ -163,12 +163,12 @@ set_property(const string &property, P3D_object *value) { if (value == NULL) { // Delete an attribute. - result = call("__del_property__", true, params, 1); + result = call("__del_property__", needs_response, params, 1); } else { // Set a new attribute. params[1] = value; - result = call("__set_property__", true, params, 2); + result = call("__set_property__", needs_response, params, 2); } P3D_OBJECT_DECREF(params[0]); diff --git a/direct/src/plugin/p3dPythonObject.h b/direct/src/plugin/p3dPythonObject.h index a05d4ec08c..8c3aed4f4e 100644 --- a/direct/src/plugin/p3dPythonObject.h +++ b/direct/src/plugin/p3dPythonObject.h @@ -42,7 +42,7 @@ public: virtual void make_string(string &value); virtual P3D_object *get_property(const string &property); - virtual bool set_property(const string &property, P3D_object *value); + virtual bool set_property(const string &property, bool needs_response, P3D_object *value); virtual bool has_method(const string &method_name); virtual P3D_object *call(const string &method_name, bool needs_response, diff --git a/direct/src/plugin/p3dSession.cxx b/direct/src/plugin/p3dSession.cxx index bda144bf81..796739da46 100644 --- a/direct/src/plugin/p3dSession.cxx +++ b/direct/src/plugin/p3dSession.cxx @@ -688,7 +688,9 @@ start_p3dpython(P3DInstance *inst) { // If we're not to be preserving the user's current directory, then // we'll need to change to the standard start directory. _keep_user_env = false; - if (inst_mgr->get_trusted_environment() && inst->_keep_user_env) { + if (inst_mgr->get_trusted_environment() && + inst_mgr->get_console_environment() && + inst->_keep_user_env) { _keep_user_env = true; } if (!_keep_user_env) { @@ -776,10 +778,13 @@ start_p3dpython(P3DInstance *inst) { _p3dpython_exe = P3D_PLUGIN_P3DPYTHON; if (_p3dpython_exe.empty()) { _p3dpython_exe = _python_root_dir + "/p3dpython"; -#ifdef _WIN32 - _p3dpython_exe += ".exe"; -#endif } +#ifdef _WIN32 + if (!inst_mgr->get_console_environment()) { + _p3dpython_exe += "w"; + } + _p3dpython_exe += ".exe"; +#endif // Populate the new process' environment. _env = string(); @@ -1191,7 +1196,7 @@ rt_terminate() { for (Instances::iterator ii = icopy.begin(); ii != icopy.end(); ++ii) { P3DInstance *inst = (*ii).second; - inst->request_stop(); + inst->request_stop_main_thread(); } } @@ -1246,8 +1251,8 @@ win_create_process() { startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); startup_info.dwFlags |= STARTF_USESTDHANDLES; - // Make sure the "python" console window is hidden. - startup_info.wShowWindow = SW_HIDE; + // We want to show the output window these days. + startup_info.wShowWindow = SW_SHOW; startup_info.dwFlags |= STARTF_USESHOWWINDOW; // If _keep_user_env, meaning not to change the current directory, diff --git a/direct/src/plugin/p3dWinSplashWindow.cxx b/direct/src/plugin/p3dWinSplashWindow.cxx index e4a9cebf5f..74d50cc6fb 100755 --- a/direct/src/plugin/p3dWinSplashWindow.cxx +++ b/direct/src/plugin/p3dWinSplashWindow.cxx @@ -137,7 +137,7 @@ set_image_filename(const string &image_filename, ImagePlacement image_placement) if (!_thread_running && _thread_continue) { // The user must have closed the window. Let's shut down the // instance, too. - _inst->request_stop(); + _inst->request_stop_main_thread(); } } } @@ -163,7 +163,7 @@ set_install_label(const string &install_label) { if (!_thread_running && _thread_continue) { // The user must have closed the window. Let's shut down the // instance, too. - _inst->request_stop(); + _inst->request_stop_main_thread(); } } } @@ -186,7 +186,7 @@ set_install_progress(double install_progress) { if (!_thread_running && _thread_continue) { // The user must have closed the window. Let's shut down the // instance, too. - _inst->request_stop(); + _inst->request_stop_main_thread(); } } } @@ -377,6 +377,9 @@ thread_run() { // Tell our parent thread that we're done. _thread_running = false; + + // Close the instance. + _inst->request_stop_sub_thread(); } //////////////////////////////////////////////////////////////////// diff --git a/direct/src/plugin/p3d_plugin.cxx b/direct/src/plugin/p3d_plugin.cxx index 3221433ec4..711774ea83 100644 --- a/direct/src/plugin/p3d_plugin.cxx +++ b/direct/src/plugin/p3d_plugin.cxx @@ -38,7 +38,7 @@ P3D_initialize(int api_version, const char *contents_filename, const char *download_url, bool verify_contents, const char *platform, const char *log_directory, const char *log_basename, - bool trusted_environment) { + bool trusted_environment, bool console_environment) { if (api_version != P3D_API_VERSION) { // Can't accept an incompatible version. return false; @@ -74,7 +74,7 @@ P3D_initialize(int api_version, const char *contents_filename, bool result = inst_mgr->initialize(contents_filename, download_url, verify_contents, platform, log_directory, log_basename, - trusted_environment); + trusted_environment, console_environment); RELEASE_LOCK(_api_lock); return result; } @@ -227,10 +227,10 @@ P3D_object_get_property(P3D_object *object, const char *property) { bool P3D_object_set_property(P3D_object *object, const char *property, - P3D_object *value) { + bool needs_response, P3D_object *value) { assert(P3DInstanceManager::get_global_ptr()->is_initialized()); ACQUIRE_LOCK(_api_lock); - bool result = P3D_OBJECT_SET_PROPERTY(object, property, value); + bool result = P3D_OBJECT_SET_PROPERTY(object, property, needs_response, value); RELEASE_LOCK(_api_lock); return result; } diff --git a/direct/src/plugin/p3d_plugin.h b/direct/src/plugin/p3d_plugin.h index add09aaf57..55b7502bf2 100644 --- a/direct/src/plugin/p3d_plugin.h +++ b/direct/src/plugin/p3d_plugin.h @@ -79,7 +79,7 @@ extern "C" { (below). This number will be incremented whenever there are changes to any of the interface specifications defined in this header file. */ -#define P3D_API_VERSION 7 +#define P3D_API_VERSION 8 /************************ GLOBAL FUNCTIONS **************************/ @@ -122,11 +122,18 @@ extern "C" { core API. Note that the individual instances also have their own log_basename values. - Finally, trusted_environment should be set true to indicate that - the environment and p3d file are already trusted. If this is set, - the current working directory will remain unchanged, and the p3d - file will be run without checking its signature. Normally, a - browser plugin should set this false. + Next, trusted_environment should be set true to indicate that the + environment and p3d file are already trusted. If this is set, the + current working directory will remain unchanged, and the p3d file + will be run without checking its signature. Normally, a browser + plugin should set this false. + + Finally, console_environment should be set true to indicate that we + are running within a text-based console, and expect to preserve the + current working directory, and also see standard output, or false + to indicate that we are running within a GUI environment, and + expect none of these. Normally, a browser plugin should set this + false. This function returns true if the core API is valid and uses a compatible API, false otherwise. If it returns false, the host @@ -137,7 +144,7 @@ P3D_initialize_func(int api_version, const char *contents_filename, const char *download_url, bool verify_contents, const char *platform, const char *log_directory, const char *log_basename, - bool trusted_environment); + bool trusted_environment, bool console_environment); /* This function should be called to unload the core API. It will release all internally-allocated memory and return the core API to @@ -439,11 +446,13 @@ P3D_object_get_property_method(P3D_object *object, const char *property); correspondingly incremented. Any existing object previously assigned to the corresponding property is replaced, and its reference count decremented. If the value pointer is NULL, the - property is removed altogether. Returns true on success, false on - failure. */ + property is removed altogether. If needs_response is true, this + method returns true on success, false on failure. If + needs_response is false, the return value is always true regardless + of success or failure.*/ typedef bool P3D_object_set_property_method(P3D_object *object, const char *property, - P3D_object *value); + bool needs_response, P3D_object *value); /* Returns true if the indicated method name exists on the object, false otherwise. In the Python case, this actually returns true if @@ -521,7 +530,7 @@ struct _P3D_object { #define P3D_OBJECT_GET_REPR(object, buffer, buffer_size) ((object)->_class->_get_repr((object), (buffer), (buffer_size))) #define P3D_OBJECT_GET_PROPERTY(object, property) ((object)->_class->_get_property((object), (property))) -#define P3D_OBJECT_SET_PROPERTY(object, property, value) ((object)->_class->_set_property((object), (property), (value))) +#define P3D_OBJECT_SET_PROPERTY(object, property, needs_response, value) ((object)->_class->_set_property((object), (property), (needs_response), (value))) #define P3D_OBJECT_HAS_METHOD(object, method_name) ((object)->_class->_has_method((object), (method_name))) #define P3D_OBJECT_CALL(object, method_name, needs_response, params, num_params) ((object)->_class->_call((object), (method_name), (needs_response), (params), (num_params))) @@ -561,7 +570,7 @@ typedef P3D_object * P3D_object_get_property_func(P3D_object *object, const char *property); typedef bool P3D_object_set_property_func(P3D_object *object, const char *property, - P3D_object *value); + bool needs_response, P3D_object *value); typedef bool P3D_object_has_method_func(P3D_object *object, const char *method_name); typedef P3D_object * diff --git a/direct/src/plugin_activex/PPBrowserObject.cpp b/direct/src/plugin_activex/PPBrowserObject.cpp index 0b26c4b290..53afc8dfac 100644 --- a/direct/src/plugin_activex/PPBrowserObject.cpp +++ b/direct/src/plugin_activex/PPBrowserObject.cpp @@ -40,9 +40,9 @@ static P3D_object* object_get_property(P3D_object *object, const char *property) } static bool object_set_property(P3D_object* object, const char* property, - P3D_object *value) + bool needs_response, P3D_object *value) { - return ((PPBrowserObject *)object)->set_property(property, value); + return ((PPBrowserObject *)object)->set_property(property, needs_response, value); } static P3D_object* object_call(P3D_object* object, const char* method_name, @@ -111,7 +111,8 @@ P3D_object* PPBrowserObject::get_property( const std::string &property ) const return m_interface->variant_to_p3dobj( &varResult ); } -bool PPBrowserObject::set_property( const std::string& property, P3D_object* value ) +bool PPBrowserObject::set_property( const std::string& property, bool needs_response, + P3D_object* value ) { assert( m_interface ); diff --git a/direct/src/plugin_activex/PPBrowserObject.h b/direct/src/plugin_activex/PPBrowserObject.h index 75e3fa8f02..a8cfc1411f 100644 --- a/direct/src/plugin_activex/PPBrowserObject.h +++ b/direct/src/plugin_activex/PPBrowserObject.h @@ -28,7 +28,8 @@ public: int get_repr( char* buffer, int buffer_length ) const; P3D_object* get_property( const std::string &property ) const; - bool set_property( const std::string& property, P3D_object* value ); + bool set_property( const std::string& property, bool needs_response, + P3D_object* value ); P3D_object* call( const std::string &method_name, P3D_object* params[], int num_params ) const; diff --git a/direct/src/plugin_activex/PPInstance.cpp b/direct/src/plugin_activex/PPInstance.cpp index 0219dfe0a2..87723ca89e 100644 --- a/direct/src/plugin_activex/PPInstance.cpp +++ b/direct/src/plugin_activex/PPInstance.cpp @@ -428,7 +428,7 @@ int PPInstance::LoadPlugin( const std::string& dllFilename ) #endif // P3D_PLUGIN_P3D_PLUGIN nout << "Attempting to load core API from " << pathname << "\n"; - if (!load_plugin(pathname, "", "", true, "", "", "", false, nout)) { + if (!load_plugin(pathname, "", "", true, "", "", "", false, false, nout)) { nout << "Unable to launch core API in " << pathname << "\n"; error = 1; } diff --git a/direct/src/plugin_activex/PPInterface.cpp b/direct/src/plugin_activex/PPInterface.cpp index fab4f079e8..edfc8d1d16 100644 --- a/direct/src/plugin_activex/PPInterface.cpp +++ b/direct/src/plugin_activex/PPInterface.cpp @@ -309,9 +309,13 @@ HRESULT PPInterface::P3DSetProperty( P3D_object* p3dObject, CString& name, DISPP } COleVariant vaArg( pdispparams->rgvarg ); P3D_object* param = variant_to_p3dobj( &vaArg ); - result = P3D_OBJECT_SET_PROPERTY( p3dObject, name, param ); + result = P3D_OBJECT_SET_PROPERTY( p3dObject, name, true, param ); P3D_OBJECT_DECREF( param ); + if (!result) { + return E_FAIL; + } + return S_OK; } diff --git a/direct/src/plugin_activex/PPPandaObject.cpp b/direct/src/plugin_activex/PPPandaObject.cpp index 345e926a54..1a3ea3b0af 100644 --- a/direct/src/plugin_activex/PPPandaObject.cpp +++ b/direct/src/plugin_activex/PPPandaObject.cpp @@ -50,6 +50,7 @@ STDMETHODIMP_(unsigned long) PPandaObject::Release() if( m_refs <= 0 ) { delete this; + return 0; } return m_refs; } diff --git a/direct/src/plugin_npapi/ppBrowserObject.cxx b/direct/src/plugin_npapi/ppBrowserObject.cxx index 038d392553..1b4f623ad1 100644 --- a/direct/src/plugin_npapi/ppBrowserObject.cxx +++ b/direct/src/plugin_npapi/ppBrowserObject.cxx @@ -38,8 +38,8 @@ object_get_property(P3D_object *object, const char *property) { static bool object_set_property(P3D_object *object, const char *property, - P3D_object *value) { - return ((PPBrowserObject *)object)->set_property(property, value); + bool needs_response, P3D_object *value) { + return ((PPBrowserObject *)object)->set_property(property, needs_response, value); } static P3D_object * @@ -158,7 +158,7 @@ get_property(const string &property) const { // success, false on failure. //////////////////////////////////////////////////////////////////// bool PPBrowserObject:: -set_property(const string &property, P3D_object *value) { +set_property(const string &property, bool needs_response, P3D_object *value) { NPIdentifier property_name = browser->getstringidentifier(property.c_str()); bool result; if (value != NULL) { diff --git a/direct/src/plugin_npapi/ppBrowserObject.h b/direct/src/plugin_npapi/ppBrowserObject.h index d18d221f07..ec87317204 100644 --- a/direct/src/plugin_npapi/ppBrowserObject.h +++ b/direct/src/plugin_npapi/ppBrowserObject.h @@ -37,7 +37,8 @@ public: int get_repr(char *buffer, int buffer_length) const; P3D_object *get_property(const string &property) const; - bool set_property(const string &property, P3D_object *value); + bool set_property(const string &property, bool needs_response, + P3D_object *value); P3D_object *call(const string &method_name, P3D_object *params[], int num_params) const; diff --git a/direct/src/plugin_npapi/ppInstance.cxx b/direct/src/plugin_npapi/ppInstance.cxx index a3d4c50987..31695ca444 100644 --- a/direct/src/plugin_npapi/ppInstance.cxx +++ b/direct/src/plugin_npapi/ppInstance.cxx @@ -1113,7 +1113,7 @@ do_load_plugin() { #endif // P3D_PLUGIN_P3D_PLUGIN nout << "Attempting to load core API from " << pathname << "\n"; - if (!load_plugin(pathname, "", "", true, "", "", "", false, nout)) { + if (!load_plugin(pathname, "", "", true, "", "", "", false, false, nout)) { nout << "Unable to launch core API in " << pathname << "\n"; return; } diff --git a/direct/src/plugin_npapi/ppPandaObject.cxx b/direct/src/plugin_npapi/ppPandaObject.cxx index 39556668b5..70787e21e4 100644 --- a/direct/src/plugin_npapi/ppPandaObject.cxx +++ b/direct/src/plugin_npapi/ppPandaObject.cxx @@ -274,7 +274,8 @@ set_property(NPIdentifier name, const NPVariant *value) { } P3D_object *object = _instance->variant_to_p3dobj(value); - bool result = P3D_OBJECT_SET_PROPERTY(_p3d_object, property_name.c_str(), object); + bool result = P3D_OBJECT_SET_PROPERTY(_p3d_object, property_name.c_str(), + true, object); P3D_OBJECT_DECREF(object); return result; } @@ -294,7 +295,8 @@ remove_property(NPIdentifier name) { return false; } - bool result = P3D_OBJECT_SET_PROPERTY(_p3d_object, property_name.c_str(), NULL); + bool result = P3D_OBJECT_SET_PROPERTY(_p3d_object, property_name.c_str(), + true, NULL); return result; } diff --git a/direct/src/plugin_standalone/panda3d.cxx b/direct/src/plugin_standalone/panda3d.cxx index fa365f13c4..46900a7458 100644 --- a/direct/src/plugin_standalone/panda3d.cxx +++ b/direct/src/plugin_standalone/panda3d.cxx @@ -52,12 +52,6 @@ Panda3D() { _root_dir = find_root_dir(); _reporting_download = false; _enable_security = false; - -#ifdef NON_CONSOLE - // For the desktop version of this program, let's always assume -S - // is in effect. - _enable_security = true; -#endif } //////////////////////////////////////////////////////////////////// @@ -555,9 +549,16 @@ get_core_api(const Filename &contents_filename, const string &download_url, bool trusted_environment = !_enable_security; +#ifdef NON_CONSOLE + static const bool console_environment = false; +#else + static const bool console_environment = true; +#endif + if (!load_plugin(pathname, contents_filename.to_os_specific(), download_url, verify_contents, this_platform, _log_dirname, - _log_basename, trusted_environment, cerr)) { + _log_basename, trusted_environment, console_environment, + cerr)) { cerr << "Unable to launch core API in " << pathname << "\n" << flush; return false; } @@ -599,7 +600,6 @@ run_getters() { void Panda3D:: handle_request(P3D_request *request) { bool handled = false; - switch (request->_request_type) { case P3D_RT_stop: delete_instance(request->_instance); @@ -1169,7 +1169,7 @@ parse_unquoted_arg(char *&p) { return strdup(result.c_str()); } -WINAPI +int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { char *command_line = GetCommandLine();