diff --git a/direct/src/plugin/p3dInstance.I b/direct/src/plugin/p3dInstance.I index 9dbf9453c6..c42d516d09 100644 --- a/direct/src/plugin/p3dInstance.I +++ b/direct/src/plugin/p3dInstance.I @@ -84,6 +84,18 @@ get_request_ready_func() const { return _func; } +//////////////////////////////////////////////////////////////////// +// Function: P3DInstance::is_trusted +// Access: Public +// Description: Returns true if this instance's p3d file is trusted +// and ready to launch, false if it needs to be approved +// by the user. +//////////////////////////////////////////////////////////////////// +inline bool P3DInstance:: +is_trusted() const { + return _p3d_trusted; +} + //////////////////////////////////////////////////////////////////// // Function: P3DInstance::is_started // Access: Public diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index 6f5c76ec0d..64ac465186 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -142,6 +142,17 @@ P3DInstance(P3D_request_ready_func *func, if (_image_package != NULL) { _image_package->add_instance(this); } + + // Check if the window size has been explicitly set to 0. This + // means we have an explicitly hidden plugin, and we should be + // prepared not to get a wparams from the browser. + if (_fparams.has_token("width") && _fparams.has_token("height") && + (_fparams.lookup_token_int("width") == 0 || + _fparams.lookup_token_int("height") == 0)) { + P3D_window_handle dummy_handle; + P3DWindowParams wparams(P3D_WT_hidden, 0, 0, 0, 0, dummy_handle); + set_wparams(wparams); + } } //////////////////////////////////////////////////////////////////// @@ -301,6 +312,7 @@ set_p3d_filename(const string &p3d_filename) { //////////////////////////////////////////////////////////////////// void P3DInstance:: set_wparams(const P3DWindowParams &wparams) { + nout << "set_wparams\n"; _got_wparams = true; _wparams = wparams; @@ -447,6 +459,7 @@ get_request() { // Also eval the associated HTML token, if any. string message = request->_request._notify._message; string expression = _fparams.lookup_token(message); + nout << "notify: " << message << " " << expression << "\n"; if (!expression.empty() && _browser_script_object != NULL) { P3D_object *result = P3D_OBJECT_EVAL(_browser_script_object, expression.c_str()); P3D_OBJECT_XDECREF(result); @@ -974,7 +987,7 @@ auth_button_clicked() { //////////////////////////////////////////////////////////////////// void P3DInstance:: play_button_clicked() { - if (_session == NULL) { + if (_session == NULL && _p3d_trusted) { set_button_image(IT_none); set_background_image(IT_launch); P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); @@ -1098,6 +1111,10 @@ mark_p3d_untrusted() { // OK, we've got the authorization program; we can put up the red // button now. + + // Notify JS that we've got no trust of the p3d file. + _panda_script_object->set_bool_property("trusted", false); + send_notify("onunauth"); set_background_image(IT_unauth); set_button_image(IT_auth_ready); make_splash_window(); @@ -1146,18 +1163,19 @@ mark_p3d_trusted() { // Until we've done all of the above processing, we haven't fully // committed to setting the trusted flag. (Setting this flag down - // here instead of up there avoids starting the instance in + // here instead of a few lines above avoids starting the instance in // scan_app_desc_file(), before we've had a chance to finish // processing this method.) _p3d_trusted = true; // Notify JS that we've accepted the trust of the p3d file. - send_notify("ontrust"); + _panda_script_object->set_bool_property("trusted", true); + send_notify("onauth"); - // Now that we're all set up, start the instance if we're fully - // downloaded. - if (get_packages_ready() && _got_wparams) { - ready_to_start(); + // Now that we're all set up, start the instance if we're already + // fully downloaded. + if (get_packages_ready()) { + mark_download_complete(); } } @@ -1780,24 +1798,37 @@ start_next_download() { _downloading_packages.clear(); if (get_packages_ready()) { - if (!_panda_script_object->get_bool_property("downloadComplete")) { - _panda_script_object->set_bool_property("downloadComplete", true); - _panda_script_object->set_string_property("status", "starting"); - send_notify("ondownloadcomplete"); - } - - // Take down the download progress bar. - if (_splash_window != NULL) { - _splash_window->set_install_progress(0.0); - _splash_window->set_install_label(""); - } - - if (_got_wparams && _p3d_trusted) { - ready_to_start(); - } + mark_download_complete(); } } +//////////////////////////////////////////////////////////////////// +// Function: P3DInstance::mark_download_complete +// Access: Private +// Description: Called internally when all files needed to launch +// have been downloaded. +//////////////////////////////////////////////////////////////////// +void P3DInstance:: +mark_download_complete() { + if (!_panda_script_object->get_bool_property("downloadComplete")) { + _panda_script_object->set_bool_property("downloadComplete", true); + _panda_script_object->set_string_property("status", "starting"); + send_notify("ondownloadcomplete"); + } + + // Take down the download progress bar. + if (_splash_window != NULL) { + _splash_window->set_install_progress(0.0); + _splash_window->set_install_label(""); + } + + nout << "ready? " << _got_wparams << " " << _p3d_trusted << "\n"; + if (_got_wparams && _p3d_trusted) { + ready_to_start(); + } +} + + //////////////////////////////////////////////////////////////////// // Function: P3DInstance::ready_to_start // Access: Private diff --git a/direct/src/plugin/p3dInstance.h b/direct/src/plugin/p3dInstance.h index 2844ff3f51..9c30f3bbe3 100644 --- a/direct/src/plugin/p3dInstance.h +++ b/direct/src/plugin/p3dInstance.h @@ -95,6 +95,7 @@ public: bool get_packages_ready() const; bool get_packages_failed() const; + inline bool is_trusted() const; void start_download(P3DDownload *download); inline bool is_started() const; void request_stop(); @@ -164,6 +165,7 @@ private: void set_button_image(ImageType image_type); void report_package_info_ready(P3DPackage *package); void start_next_download(); + void mark_download_complete(); void ready_to_start(); void report_instance_progress(double progress); void report_package_progress(P3DPackage *package, double progress); diff --git a/direct/src/plugin/p3dMainObject.cxx b/direct/src/plugin/p3dMainObject.cxx index 0c52a3bc00..51d28a11ec 100644 --- a/direct/src/plugin/p3dMainObject.cxx +++ b/direct/src/plugin/p3dMainObject.cxx @@ -27,6 +27,7 @@ P3DMainObject:: P3DMainObject() : _pyobj(NULL) { + _unauth_play = false; } //////////////////////////////////////////////////////////////////// @@ -183,7 +184,7 @@ set_property(const string &property, P3D_object *value) { bool P3DMainObject:: has_method(const string &method_name) { // Some special-case methods implemented in-place. - if (method_name == "start") { + if (method_name == "play") { return true; } else if (method_name == "read_game_log") { return true; @@ -215,8 +216,8 @@ has_method(const string &method_name) { P3D_object *P3DMainObject:: call(const string &method_name, bool needs_response, P3D_object *params[], int num_params) { - if (method_name == "start") { - return call_start(params, num_params); + if (method_name == "play") { + return call_play(params, num_params); } else if (method_name == "read_game_log") { return call_read_game_log(params, num_params); } else if (method_name == "read_system_log") { @@ -298,22 +299,39 @@ set_instance(P3DInstance *inst) { } //////////////////////////////////////////////////////////////////// -// Function: P3DMainObject::call_start +// Function: P3DMainObject::call_play // Access: Private -// Description: Starts the process remotely, as if the start button -// had been clicked. Only applicable if the application -// was in the ready state. Returns true if the +// Description: Starts the process remotely, as if the play button +// had been clicked. If the application has not yet +// been validated, this pops up the validation dialog. +// +// Only applicable if the application was in the ready +// state, or the unauth state. Returns true if the // application is now started, false otherwise. +// +// This may be invoked from the unauth state only once. +// If the user chooses not to authorize the plugin at +// that time, it may not be invoked automatically again. //////////////////////////////////////////////////////////////////// P3D_object *P3DMainObject:: -call_start(P3D_object *params[], int num_params) { +call_play(P3D_object *params[], int num_params) { P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr(); if (_inst == NULL) { return inst_mgr->new_bool_object(false); } - if (!_inst->is_started()) { - _inst->play_button_clicked(); + if (!_inst->is_trusted()) { + // Requires authorization. We allow this only once; beyond that, + // and you're only annoying the user. + if (!_unauth_play) { + _unauth_play = true; + _inst->splash_button_clicked_main_thread(); + } + + } else if (!_inst->is_started()) { + // We allow calling play() from a ready state without limit, but + // probably only once will be necessary. + _inst->splash_button_clicked_main_thread(); } return inst_mgr->new_bool_object(_inst->is_started()); diff --git a/direct/src/plugin/p3dMainObject.h b/direct/src/plugin/p3dMainObject.h index 8bc60c23b9..860078c140 100644 --- a/direct/src/plugin/p3dMainObject.h +++ b/direct/src/plugin/p3dMainObject.h @@ -67,7 +67,7 @@ public: void set_instance(P3DInstance *inst); private: - P3D_object *call_start(P3D_object *params[], int num_params); + P3D_object *call_play(P3D_object *params[], int num_params); P3D_object *call_read_game_log(P3D_object *params[], int num_params); P3D_object *call_read_system_log(P3D_object *params[], int num_params); P3D_object *read_log(const string &log_pathname, @@ -77,6 +77,8 @@ private: P3D_object *_pyobj; P3DInstance *_inst; + bool _unauth_play; + // This map is used to store properties and retrieve until // set_pyobj() is called for the firs ttime. At that point, the // properties stored here are transferred down to the internal