add p3dpythonw.exe, more robust startup

This commit is contained in:
David Rose 2009-10-06 18:55:28 +00:00
parent f7566dc280
commit a308a4a01c
30 changed files with 296 additions and 90 deletions

View File

@ -2411,6 +2411,8 @@ class Packager:
# extensions are automatically replaced with the appropriate # extensions are automatically replaced with the appropriate
# platform-specific extensions. # platform-specific extensions.
self.do_file('p3dpython.exe') self.do_file('p3dpython.exe')
if PandaSystem.getPlatform().startswith('win'):
self.do_file('p3dpythonw.exe')
self.do_file('libp3dpython.dll') self.do_file('libp3dpython.dll')
def do_freeze(self, filename, compileToExe = False): def do_freeze(self, filename, compileToExe = False):

View File

@ -183,6 +183,52 @@
#define WIN_SYS_LIBS user32.lib #define WIN_SYS_LIBS user32.lib
#end bin_target #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 #begin static_lib_target
#define BUILD_TARGET $[and $[HAVE_TINYXML],$[HAVE_OPENSSL]] #define BUILD_TARGET $[and $[HAVE_TINYXML],$[HAVE_OPENSSL]]
#define TARGET plugin_common #define TARGET plugin_common

View File

@ -128,7 +128,7 @@ load_plugin(const string &p3d_plugin_filename,
const string &contents_filename, const string &download_url, const string &contents_filename, const string &download_url,
bool verify_contents, const string &platform, bool verify_contents, const string &platform,
const string &log_directory, const string &log_basename, const string &log_directory, const string &log_basename,
bool trusted_environment, bool trusted_environment, bool console_environment,
ostream &logfile) { ostream &logfile) {
string filename = p3d_plugin_filename; string filename = p3d_plugin_filename;
if (filename.empty()) { if (filename.empty()) {
@ -313,7 +313,7 @@ load_plugin(const string &p3d_plugin_filename,
if (!P3D_initialize(P3D_API_VERSION, contents_filename.c_str(), if (!P3D_initialize(P3D_API_VERSION, contents_filename.c_str(),
download_url.c_str(), verify_contents, platform.c_str(), download_url.c_str(), verify_contents, platform.c_str(),
log_directory.c_str(), log_basename.c_str(), log_directory.c_str(), log_basename.c_str(),
trusted_environment)) { trusted_environment, console_environment)) {
// Oops, failure to initialize. // Oops, failure to initialize.
logfile << "Failed to initialize plugin (wrong API version?)\n"; logfile << "Failed to initialize plugin (wrong API version?)\n";
unload_plugin(); unload_plugin();

View File

@ -64,7 +64,7 @@ load_plugin(const string &p3d_plugin_filename,
const string &contents_filename, const string &download_url, const string &contents_filename, const string &download_url,
bool verify_contents, const string &platform, bool verify_contents, const string &platform,
const string &log_directory, const string &log_basename, const string &log_directory, const string &log_basename,
bool trusted_environment, bool trusted_environment, bool console_environment,
ostream &logfile); ostream &logfile);
void unload_plugin(); void unload_plugin();
bool is_plugin_loaded(); bool is_plugin_loaded();

View File

@ -864,15 +864,54 @@ start_download(P3DDownload *download) {
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: P3DInstance::request_stop // Function: P3DInstance::request_stop_sub_thread
// Access: Public // Access: Public
// Description: Asks the host to shut down this particular instance, // Description: Asks the host to shut down this particular instance,
// presumably because the user has indicated it should // presumably because the user has indicated it should
// exit. // exit. This call may be made in any thread.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void P3DInstance:: void P3DInstance::
request_stop() { request_stop_sub_thread() {
// Atomically check _requested_stop.
bool add_request = false;
ACQUIRE_LOCK(_request_lock);
if (!_requested_stop) { 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; _requested_stop = true;
P3D_request *request = new P3D_request; P3D_request *request = new P3D_request;
request->_request_type = P3D_RT_stop; request->_request_type = P3D_RT_stop;
@ -1533,7 +1572,7 @@ handle_script_request(const string &operation, P3D_object *object,
} else if (operation == "set_property") { } else if (operation == "set_property") {
bool result = 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"); TiXmlElement *xvalue = new TiXmlElement("value");
xvalue->SetAttribute("type", "bool"); xvalue->SetAttribute("type", "bool");
@ -1541,7 +1580,7 @@ handle_script_request(const string &operation, P3D_object *object,
xcommand->LinkEndChild(xvalue); xcommand->LinkEndChild(xvalue);
} else if (operation == "del_property") { } 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"); TiXmlElement *xvalue = new TiXmlElement("value");
xvalue->SetAttribute("type", "bool"); xvalue->SetAttribute("type", "bool");

View File

@ -98,7 +98,8 @@ public:
inline bool is_trusted() const; inline bool is_trusted() const;
void start_download(P3DDownload *download); void start_download(P3DDownload *download);
inline bool is_started() const; inline bool is_started() const;
void request_stop(); void request_stop_sub_thread();
void request_stop_main_thread();
void request_refresh(); void request_refresh();
TiXmlElement *make_xml(); TiXmlElement *make_xml();

View File

@ -127,13 +127,31 @@ get_log_pathname() const {
// file will be run without checking its signature. // file will be run without checking its signature.
// //
// This should generally be true only when run by // 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:: inline bool P3DInstanceManager::
get_trusted_environment() const { get_trusted_environment() const {
return _trusted_environment; 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 // Function: P3DInstanceManager::get_super_mirror
// Access: Public // Access: Public

View File

@ -172,8 +172,10 @@ bool P3DInstanceManager::
initialize(const string &contents_filename, const string &download_url, initialize(const string &contents_filename, const string &download_url,
bool verify_contents, bool verify_contents,
const string &platform, const string &log_directory, 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; _trusted_environment = trusted_environment;
_console_environment = console_environment;
_verify_contents = verify_contents; _verify_contents = verify_contents;
_platform = platform; _platform = platform;
if (_platform.empty()) { if (_platform.empty()) {

View File

@ -55,7 +55,8 @@ public:
const string &platform, const string &platform,
const string &log_directory, const string &log_directory,
const string &log_basename, const string &log_basename,
bool trusted_environment); bool trusted_environment,
bool console_environment);
inline bool is_initialized() const; inline bool is_initialized() const;
inline bool get_verify_contents() const; inline bool get_verify_contents() const;
@ -67,6 +68,7 @@ public:
inline const string &get_log_directory() const; inline const string &get_log_directory() const;
inline const string &get_log_pathname() const; inline const string &get_log_pathname() const;
inline bool get_trusted_environment() const; inline bool get_trusted_environment() const;
inline bool get_console_environment() const;
void set_super_mirror(const string &super_mirror_url); void set_super_mirror(const string &super_mirror_url);
inline const string &get_super_mirror() const; inline const string &get_super_mirror() const;
@ -133,6 +135,7 @@ private:
string _log_pathname; string _log_pathname;
string _temp_directory; string _temp_directory;
bool _trusted_environment; bool _trusted_environment;
bool _console_environment;
string _super_mirror_url; string _super_mirror_url;
P3D_object *_undefined_object; P3D_object *_undefined_object;

View File

@ -143,7 +143,7 @@ get_property(const string &property) {
// success, false on failure. // success, false on failure.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool P3DMainObject:: 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. // First, we set the property locally.
if (value != NULL) { if (value != NULL) {
Properties::iterator pi; Properties::iterator pi;
@ -172,7 +172,7 @@ set_property(const string &property, P3D_object *value) {
} }
// With a pyobj, we also pass this request down. // 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) { for (pi = _properties.begin(); pi != _properties.end(); ++pi) {
const string &property_name = (*pi).first; const string &property_name = (*pi).first;
P3D_object *value = (*pi).second; 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);
} }
} }
} }

View File

@ -53,7 +53,8 @@ public:
virtual void make_string(string &value); virtual void make_string(string &value);
virtual P3D_object *get_property(const string &property); 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 bool has_method(const string &method_name);
virtual P3D_object *call(const string &method_name, bool needs_response, virtual P3D_object *call(const string &method_name, bool needs_response,

View File

@ -65,8 +65,8 @@ object_get_property(P3D_object *object, const char *property) {
static bool static bool
object_set_property(P3D_object *object, const char *property, object_set_property(P3D_object *object, const char *property,
P3D_object *value) { bool needs_response, P3D_object *value) {
return ((P3DObject *)object)->set_property(property, value); return ((P3DObject *)object)->set_property(property, needs_response, value);
} }
static bool static bool
@ -155,7 +155,7 @@ generic_get_property(P3D_object *object, const char *property) {
static bool static bool
generic_set_property(P3D_object *object, const char *property, generic_set_property(P3D_object *object, const char *property,
P3D_object *value) { bool needs_response, P3D_object *value) {
return false; return false;
} }
@ -275,7 +275,7 @@ get_property(const string &property) {
// success, false on failure. // success, false on failure.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool P3DObject:: bool P3DObject::
set_property(const string &property, P3D_object *value) { set_property(const string &property, bool needs_response, P3D_object *value) {
return false; return false;
} }
@ -398,12 +398,11 @@ get_bool_property(const string &property) {
// Description: Changes the value of the named property to the // Description: Changes the value of the named property to the
// indicated boolean value. // indicated boolean value.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool P3DObject:: void P3DObject::
set_bool_property(const string &property, bool value) { set_bool_property(const string &property, bool value) {
P3D_object *bvalue = new P3DBoolObject(value); P3D_object *bvalue = new P3DBoolObject(value);
bool result = set_property(property, bvalue); set_property(property, false, bvalue);
P3D_OBJECT_DECREF(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 // Description: Changes the value of the named property to the
// indicated integer value. // indicated integer value.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool P3DObject:: void P3DObject::
set_int_property(const string &property, int value) { set_int_property(const string &property, int value) {
P3D_object *ivalue = new P3DIntObject(value); P3D_object *ivalue = new P3DIntObject(value);
bool result = set_property(property, ivalue); set_property(property, false, ivalue);
P3D_OBJECT_DECREF(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 // Description: Changes the value of the named property to the
// indicated floating-point value. // indicated floating-point value.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool P3DObject:: void P3DObject::
set_float_property(const string &property, double value) { set_float_property(const string &property, double value) {
P3D_object *fvalue = new P3DFloatObject(value); P3D_object *fvalue = new P3DFloatObject(value);
bool result = set_property(property, fvalue); set_property(property, false, fvalue);
P3D_OBJECT_DECREF(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 // Description: Changes the value of the named property to the
// indicated string value. // indicated string value.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool P3DObject:: void P3DObject::
set_string_property(const string &property, const string &value) { set_string_property(const string &property, const string &value) {
P3D_object *svalue = new P3DStringObject(value); P3D_object *svalue = new P3DStringObject(value);
bool result = set_property(property, svalue); set_property(property, false, svalue);
P3D_OBJECT_DECREF(svalue); P3D_OBJECT_DECREF(svalue);
return result;
} }

View File

@ -43,7 +43,8 @@ public:
virtual void make_string(string &value)=0; virtual void make_string(string &value)=0;
virtual P3D_object *get_property(const string &property); 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 bool has_method(const string &method_name);
virtual P3D_object *call(const string &method_name, bool needs_response, virtual P3D_object *call(const string &method_name, bool needs_response,
@ -57,16 +58,16 @@ public:
// Convenience functions. // Convenience functions.
bool get_bool_property(const string &property); 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); 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); 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); 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: public:
static P3D_class_definition _object_class; static P3D_class_definition _object_class;

View File

@ -16,6 +16,8 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <vector>
#include <assert.h>
#include <string.h> // strrchr #include <string.h> // strrchr
using namespace std; using namespace std;
@ -24,6 +26,74 @@ using namespace std;
extern "C" { void CPSEnableForegroundOperation(ProcessSerialNumber* psn); } extern "C" { void CPSEnableForegroundOperation(ProcessSerialNumber* psn); }
#endif #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<char *> 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 // Function: main
// Description: This is a trivial main() function that invokes // Description: This is a trivial main() function that invokes

View File

@ -153,8 +153,8 @@ get_property(const string &property) {
// success, false on failure. // success, false on failure.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool P3DPythonObject:: bool P3DPythonObject::
set_property(const string &property, P3D_object *value) { set_property(const string &property, bool needs_response, P3D_object *value) {
bool bresult = false; bool bresult = !needs_response;
P3D_object *params[2]; P3D_object *params[2];
params[0] = new P3DStringObject(property); params[0] = new P3DStringObject(property);
@ -163,12 +163,12 @@ set_property(const string &property, P3D_object *value) {
if (value == NULL) { if (value == NULL) {
// Delete an attribute. // Delete an attribute.
result = call("__del_property__", true, params, 1); result = call("__del_property__", needs_response, params, 1);
} else { } else {
// Set a new attribute. // Set a new attribute.
params[1] = value; params[1] = value;
result = call("__set_property__", true, params, 2); result = call("__set_property__", needs_response, params, 2);
} }
P3D_OBJECT_DECREF(params[0]); P3D_OBJECT_DECREF(params[0]);

View File

@ -42,7 +42,7 @@ public:
virtual void make_string(string &value); virtual void make_string(string &value);
virtual P3D_object *get_property(const string &property); 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 bool has_method(const string &method_name);
virtual P3D_object *call(const string &method_name, bool needs_response, virtual P3D_object *call(const string &method_name, bool needs_response,

View File

@ -688,7 +688,9 @@ start_p3dpython(P3DInstance *inst) {
// If we're not to be preserving the user's current directory, then // If we're not to be preserving the user's current directory, then
// we'll need to change to the standard start directory. // we'll need to change to the standard start directory.
_keep_user_env = false; _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; _keep_user_env = true;
} }
if (!_keep_user_env) { if (!_keep_user_env) {
@ -776,10 +778,13 @@ start_p3dpython(P3DInstance *inst) {
_p3dpython_exe = P3D_PLUGIN_P3DPYTHON; _p3dpython_exe = P3D_PLUGIN_P3DPYTHON;
if (_p3dpython_exe.empty()) { if (_p3dpython_exe.empty()) {
_p3dpython_exe = _python_root_dir + "/p3dpython"; _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. // Populate the new process' environment.
_env = string(); _env = string();
@ -1191,7 +1196,7 @@ rt_terminate() {
for (Instances::iterator ii = icopy.begin(); ii != icopy.end(); ++ii) { for (Instances::iterator ii = icopy.begin(); ii != icopy.end(); ++ii) {
P3DInstance *inst = (*ii).second; 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.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
startup_info.dwFlags |= STARTF_USESTDHANDLES; startup_info.dwFlags |= STARTF_USESTDHANDLES;
// Make sure the "python" console window is hidden. // We want to show the output window these days.
startup_info.wShowWindow = SW_HIDE; startup_info.wShowWindow = SW_SHOW;
startup_info.dwFlags |= STARTF_USESHOWWINDOW; startup_info.dwFlags |= STARTF_USESHOWWINDOW;
// If _keep_user_env, meaning not to change the current directory, // If _keep_user_env, meaning not to change the current directory,

View File

@ -137,7 +137,7 @@ set_image_filename(const string &image_filename, ImagePlacement image_placement)
if (!_thread_running && _thread_continue) { if (!_thread_running && _thread_continue) {
// The user must have closed the window. Let's shut down the // The user must have closed the window. Let's shut down the
// instance, too. // 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) { if (!_thread_running && _thread_continue) {
// The user must have closed the window. Let's shut down the // The user must have closed the window. Let's shut down the
// instance, too. // 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) { if (!_thread_running && _thread_continue) {
// The user must have closed the window. Let's shut down the // The user must have closed the window. Let's shut down the
// instance, too. // instance, too.
_inst->request_stop(); _inst->request_stop_main_thread();
} }
} }
} }
@ -377,6 +377,9 @@ thread_run() {
// Tell our parent thread that we're done. // Tell our parent thread that we're done.
_thread_running = false; _thread_running = false;
// Close the instance.
_inst->request_stop_sub_thread();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -38,7 +38,7 @@ P3D_initialize(int api_version, const char *contents_filename,
const char *download_url, bool verify_contents, const char *download_url, bool verify_contents,
const char *platform, const char *platform,
const char *log_directory, const char *log_basename, const char *log_directory, const char *log_basename,
bool trusted_environment) { bool trusted_environment, bool console_environment) {
if (api_version != P3D_API_VERSION) { if (api_version != P3D_API_VERSION) {
// Can't accept an incompatible version. // Can't accept an incompatible version.
return false; return false;
@ -74,7 +74,7 @@ P3D_initialize(int api_version, const char *contents_filename,
bool result = inst_mgr->initialize(contents_filename, download_url, bool result = inst_mgr->initialize(contents_filename, download_url,
verify_contents, platform, verify_contents, platform,
log_directory, log_basename, log_directory, log_basename,
trusted_environment); trusted_environment, console_environment);
RELEASE_LOCK(_api_lock); RELEASE_LOCK(_api_lock);
return result; return result;
} }
@ -227,10 +227,10 @@ P3D_object_get_property(P3D_object *object, const char *property) {
bool bool
P3D_object_set_property(P3D_object *object, const char *property, 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()); assert(P3DInstanceManager::get_global_ptr()->is_initialized());
ACQUIRE_LOCK(_api_lock); 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); RELEASE_LOCK(_api_lock);
return result; return result;
} }

View File

@ -79,7 +79,7 @@ extern "C" {
(below). This number will be incremented whenever there are changes (below). This number will be incremented whenever there are changes
to any of the interface specifications defined in this header to any of the interface specifications defined in this header
file. */ file. */
#define P3D_API_VERSION 7 #define P3D_API_VERSION 8
/************************ GLOBAL FUNCTIONS **************************/ /************************ GLOBAL FUNCTIONS **************************/
@ -122,11 +122,18 @@ extern "C" {
core API. Note that the individual instances also have their own core API. Note that the individual instances also have their own
log_basename values. log_basename values.
Finally, trusted_environment should be set true to indicate that Next, trusted_environment should be set true to indicate that the
the environment and p3d file are already trusted. If this is set, environment and p3d file are already trusted. If this is set, the
the current working directory will remain unchanged, and the p3d current working directory will remain unchanged, and the p3d file
file will be run without checking its signature. Normally, a will be run without checking its signature. Normally, a browser
browser plugin should set this false. 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 This function returns true if the core API is valid and uses a
compatible API, false otherwise. If it returns false, the host 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 *download_url, bool verify_contents,
const char *platform, const char *platform,
const char *log_directory, const char *log_basename, 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 /* This function should be called to unload the core API. It will
release all internally-allocated memory and return the core API to 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 correspondingly incremented. Any existing object previously
assigned to the corresponding property is replaced, and its assigned to the corresponding property is replaced, and its
reference count decremented. If the value pointer is NULL, the reference count decremented. If the value pointer is NULL, the
property is removed altogether. Returns true on success, false on property is removed altogether. If needs_response is true, this
failure. */ 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 typedef bool
P3D_object_set_property_method(P3D_object *object, const char *property, 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, /* Returns true if the indicated method name exists on the object,
false otherwise. In the Python case, this actually returns true if 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_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_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_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))) #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); P3D_object_get_property_func(P3D_object *object, const char *property);
typedef bool typedef bool
P3D_object_set_property_func(P3D_object *object, const char *property, P3D_object_set_property_func(P3D_object *object, const char *property,
P3D_object *value); bool needs_response, P3D_object *value);
typedef bool typedef bool
P3D_object_has_method_func(P3D_object *object, const char *method_name); P3D_object_has_method_func(P3D_object *object, const char *method_name);
typedef P3D_object * typedef P3D_object *

View File

@ -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, 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, 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 ); 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 ); assert( m_interface );

View File

@ -28,7 +28,8 @@ public:
int get_repr( char* buffer, int buffer_length ) const; int get_repr( char* buffer, int buffer_length ) const;
P3D_object* get_property( const std::string &property ) 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* call( const std::string &method_name,
P3D_object* params[], int num_params ) const; P3D_object* params[], int num_params ) const;

View File

@ -428,7 +428,7 @@ int PPInstance::LoadPlugin( const std::string& dllFilename )
#endif // P3D_PLUGIN_P3D_PLUGIN #endif // P3D_PLUGIN_P3D_PLUGIN
nout << "Attempting to load core API from " << pathname << "\n"; 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"; nout << "Unable to launch core API in " << pathname << "\n";
error = 1; error = 1;
} }

View File

@ -309,9 +309,13 @@ HRESULT PPInterface::P3DSetProperty( P3D_object* p3dObject, CString& name, DISPP
} }
COleVariant vaArg( pdispparams->rgvarg ); COleVariant vaArg( pdispparams->rgvarg );
P3D_object* param = variant_to_p3dobj( &vaArg ); 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 ); P3D_OBJECT_DECREF( param );
if (!result) {
return E_FAIL;
}
return S_OK; return S_OK;
} }

View File

@ -50,6 +50,7 @@ STDMETHODIMP_(unsigned long) PPandaObject::Release()
if( m_refs <= 0 ) if( m_refs <= 0 )
{ {
delete this; delete this;
return 0;
} }
return m_refs; return m_refs;
} }

View File

@ -38,8 +38,8 @@ object_get_property(P3D_object *object, const char *property) {
static bool static bool
object_set_property(P3D_object *object, const char *property, 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 * static P3D_object *
@ -158,7 +158,7 @@ get_property(const string &property) const {
// success, false on failure. // success, false on failure.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool PPBrowserObject:: 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()); NPIdentifier property_name = browser->getstringidentifier(property.c_str());
bool result; bool result;
if (value != NULL) { if (value != NULL) {

View File

@ -37,7 +37,8 @@ public:
int get_repr(char *buffer, int buffer_length) const; int get_repr(char *buffer, int buffer_length) const;
P3D_object *get_property(const string &property) 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 *call(const string &method_name,
P3D_object *params[], int num_params) const; P3D_object *params[], int num_params) const;

View File

@ -1113,7 +1113,7 @@ do_load_plugin() {
#endif // P3D_PLUGIN_P3D_PLUGIN #endif // P3D_PLUGIN_P3D_PLUGIN
nout << "Attempting to load core API from " << pathname << "\n"; 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"; nout << "Unable to launch core API in " << pathname << "\n";
return; return;
} }

View File

@ -274,7 +274,8 @@ set_property(NPIdentifier name, const NPVariant *value) {
} }
P3D_object *object = _instance->variant_to_p3dobj(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); P3D_OBJECT_DECREF(object);
return result; return result;
} }
@ -294,7 +295,8 @@ remove_property(NPIdentifier name) {
return false; 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; return result;
} }

View File

@ -52,12 +52,6 @@ Panda3D() {
_root_dir = find_root_dir(); _root_dir = find_root_dir();
_reporting_download = false; _reporting_download = false;
_enable_security = 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; 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(), if (!load_plugin(pathname, contents_filename.to_os_specific(),
download_url, verify_contents, this_platform, _log_dirname, 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; cerr << "Unable to launch core API in " << pathname << "\n" << flush;
return false; return false;
} }
@ -599,7 +600,6 @@ run_getters() {
void Panda3D:: void Panda3D::
handle_request(P3D_request *request) { handle_request(P3D_request *request) {
bool handled = false; bool handled = false;
switch (request->_request_type) { switch (request->_request_type) {
case P3D_RT_stop: case P3D_RT_stop:
delete_instance(request->_instance); delete_instance(request->_instance);
@ -1169,7 +1169,7 @@ parse_unquoted_arg(char *&p) {
return strdup(result.c_str()); return strdup(result.c_str());
} }
WINAPI int WINAPI
WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
char *command_line = GetCommandLine(); char *command_line = GetCommandLine();