From 01ced750071f597bb64a2053ee583f2f85ad5ab6 Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 24 Jun 2009 22:02:13 +0000 Subject: [PATCH] progress bars are back --- direct/src/plugin/Sources.pp | 4 - direct/src/plugin/p3dInstance.cxx | 30 +- direct/src/plugin/p3dInstance.h | 4 +- direct/src/plugin/p3dProgressWindow.I | 14 - direct/src/plugin/p3dProgressWindow.cxx | 54 --- direct/src/plugin/p3dProgressWindow.h | 52 --- direct/src/plugin/p3dPythonRun.cxx | 1 + direct/src/plugin/p3dSession.cxx | 88 +++-- direct/src/plugin/p3dSession.h | 16 +- direct/src/plugin/p3dSplashWindow.cxx | 30 +- direct/src/plugin/p3dSplashWindow.h | 5 +- direct/src/plugin/p3dWinProgressWindow.I | 14 - direct/src/plugin/p3dWinProgressWindow.cxx | 354 -------------------- direct/src/plugin/p3dWinProgressWindow.h | 72 ---- direct/src/plugin/p3dWinSplashWindow.cxx | 274 ++++++++++++++- direct/src/plugin/p3dWinSplashWindow.h | 31 +- direct/src/plugin/p3d_plugin_composite1.cxx | 2 - direct/src/plugin_npapi/ppInstance.cxx | 13 +- direct/src/plugin_npapi/startup.cxx | 98 +++--- direct/src/plugin_standalone/panda3d.cxx | 15 +- direct/src/showutil/runp3d.py | 1 - 21 files changed, 474 insertions(+), 698 deletions(-) delete mode 100755 direct/src/plugin/p3dProgressWindow.I delete mode 100755 direct/src/plugin/p3dProgressWindow.cxx delete mode 100755 direct/src/plugin/p3dProgressWindow.h delete mode 100755 direct/src/plugin/p3dWinProgressWindow.I delete mode 100755 direct/src/plugin/p3dWinProgressWindow.cxx delete mode 100755 direct/src/plugin/p3dWinProgressWindow.h diff --git a/direct/src/plugin/Sources.pp b/direct/src/plugin/Sources.pp index 738b484deb..9b22815a14 100644 --- a/direct/src/plugin/Sources.pp +++ b/direct/src/plugin/Sources.pp @@ -23,11 +23,9 @@ p3dInstanceManager.h p3dInstanceManager.I \ p3dMultifileReader.h p3dMultifileReader.I \ p3dPackage.h p3dPackage.I \ - p3dProgressWindow.h p3dProgressWindow.I \ p3dSession.h p3dSession.I \ p3dSplashWindow.h p3dSplashWindow.I \ p3dWindowParams.h p3dWindowParams.I \ - p3dWinProgressWindow.h p3dWinProgressWindow.I \ p3dWinSplashWindow.h p3dWinSplashWindow.I #define INCLUDED_SOURCES \ @@ -39,11 +37,9 @@ p3dInstanceManager.cxx \ p3dMultifileReader.cxx \ p3dPackage.cxx \ - p3dProgressWindow.cxx \ p3dSplashWindow.cxx \ p3dSession.cxx \ p3dWindowParams.cxx \ - p3dWinProgressWindow.cxx \ p3dWinSplashWindow.cxx #define INSTALL_HEADERS \ diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index c0caccc8c1..45f365aa21 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -76,7 +76,7 @@ P3DInstance:: _packages.clear(); if (_splash_window != NULL) { - _splash_window->close_window(); + nout << "Deleting splash window in destructor\n" << flush; delete _splash_window; _splash_window = NULL; } @@ -98,9 +98,11 @@ set_fparams(const P3DFileParams &fparams) { _got_fparams = true; _fparams = fparams; - // Update the splash window. - if (_splash_window != NULL) { - _splash_window->set_fparams(_fparams); + // Maybe create the splash window. + if (!_instance_window_opened && _got_wparams) { + if (_splash_window == NULL) { + _splash_window = new SplashWindowType(this); + } } // This also sets up some internal data based on the contents of the @@ -128,10 +130,9 @@ set_wparams(const P3DWindowParams &wparams) { _wparams = wparams; // Update or create the splash window. - if (!_instance_window_opened) { + if (!_instance_window_opened && _got_fparams) { if (_splash_window == NULL) { _splash_window = new SplashWindowType(this); - _splash_window->open_window(); } else { _splash_window->set_wparams(_wparams); } @@ -238,7 +239,7 @@ get_request() { nout << "Instance " << this << " got window_opened\n" << flush; _instance_window_opened = true; if (_splash_window != NULL) { - _splash_window->close_window(); + nout << "Deleting splash window\n" << flush; delete _splash_window; _splash_window = NULL; } @@ -257,6 +258,8 @@ get_request() { //////////////////////////////////////////////////////////////////// void P3DInstance:: add_request(P3D_request *request) { + nout << "Instance " << this << " add_request(" << request->_request_type + << ")\n" << flush; request->_instance = this; ACQUIRE_LOCK(_request_lock); @@ -414,3 +417,16 @@ make_xml() { return xinstance; } + +//////////////////////////////////////////////////////////////////// +// Function: P3DInstance::install_progress +// Access: Private +// Description: Notified as the _panda3d package is downloaded. +//////////////////////////////////////////////////////////////////// +void P3DInstance:: +install_progress(P3DPackage *package, double progress) { + if (_splash_window != NULL) { + _splash_window->set_install_label("Installing Panda3D"); + _splash_window->set_install_progress(progress); + } +} diff --git a/direct/src/plugin/p3dInstance.h b/direct/src/plugin/p3dInstance.h index d4a834ad67..710a688fce 100644 --- a/direct/src/plugin/p3dInstance.h +++ b/direct/src/plugin/p3dInstance.h @@ -71,11 +71,11 @@ public: inline bool is_started() const; void request_stop(); - void async_notify(const string &message); - TiXmlElement *make_xml(); private: + void install_progress(P3DPackage *package, double progress); + P3D_request_ready_func *_func; bool _got_fparams; diff --git a/direct/src/plugin/p3dProgressWindow.I b/direct/src/plugin/p3dProgressWindow.I deleted file mode 100755 index 720f3ecfbd..0000000000 --- a/direct/src/plugin/p3dProgressWindow.I +++ /dev/null @@ -1,14 +0,0 @@ -// Filename: p3dProgressWindow.I -// Created by: drose (17Jun09) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised BSD -// license. You should have received a copy of this license along -// with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// - diff --git a/direct/src/plugin/p3dProgressWindow.cxx b/direct/src/plugin/p3dProgressWindow.cxx deleted file mode 100755 index 5f2bcfe9e8..0000000000 --- a/direct/src/plugin/p3dProgressWindow.cxx +++ /dev/null @@ -1,54 +0,0 @@ -// Filename: p3dProgressWindow.cxx -// Created by: drose (17Jun09) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised BSD -// license. You should have received a copy of this license along -// with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// - -#include "p3dProgressWindow.h" - -//////////////////////////////////////////////////////////////////// -// Function: P3DProgressWindow::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -P3DProgressWindow:: -P3DProgressWindow(P3DPackage *package, P3DSession *session, - P3DInstance *inst) : - _package(package), - _session(session), - _inst(inst) -{ -} - -//////////////////////////////////////////////////////////////////// -// Function: P3DProgressWindow::package_ready -// Access: Public, Virtual -// Description: -//////////////////////////////////////////////////////////////////// -void P3DProgressWindow:: -package_ready(P3DPackage *package, bool success) { - if (this == _session->_panda3d_callback) { - _session->_panda3d_callback = NULL; - if (package == _session->_panda3d) { - if (success) { - _session->start_p3dpython(); - } else { - nout << "Failed to install " << package->get_package_name() - << "_" << package->get_package_version() << "\n"; - } - } else { - nout << "Unexpected panda3d package: " << package << "\n"; - } - } else { - nout << "Unexpected callback for P3DSession\n"; - } -} - diff --git a/direct/src/plugin/p3dProgressWindow.h b/direct/src/plugin/p3dProgressWindow.h deleted file mode 100755 index 242d610352..0000000000 --- a/direct/src/plugin/p3dProgressWindow.h +++ /dev/null @@ -1,52 +0,0 @@ -// Filename: p3dProgressWindow.h -// Created by: drose (17Jun09) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised BSD -// license. You should have received a copy of this license along -// with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// - - -#ifndef P3DPROGRESSWINDOW_H -#define P3DPROGRESSWINDOW_H - -#include "p3d_plugin_common.h" -#include "p3dPackage.h" -#include "p3dWindowParams.h" - -class P3DInstance; - -//////////////////////////////////////////////////////////////////// -// Class : P3DProgressWindow -// Description : This window is displayed temporarily, in place of an -// instance's actual window, during the initial download -// of the Panda3D code. When the download is finished, -// it notifies the session. -// -// This is the base implementation; it contains no -// specific code to open a window. -//////////////////////////////////////////////////////////////////// -class P3DProgressWindow : public P3DPackage::Callback { -public: - P3DProgressWindow(P3DPackage *package, P3DSession *session, - P3DInstance *inst); - - virtual void package_ready(P3DPackage *package, bool success); - -protected: - P3DPackage *_package; - P3DSession *_session; - P3DInstance *_inst; - - P3DWindowParams _wparams; -}; - -#include "p3dProgressWindow.I" - -#endif diff --git a/direct/src/plugin/p3dPythonRun.cxx b/direct/src/plugin/p3dPythonRun.cxx index b16044a07e..be5ea22383 100755 --- a/direct/src/plugin/p3dPythonRun.cxx +++ b/direct/src/plugin/p3dPythonRun.cxx @@ -299,6 +299,7 @@ py_request_func(PyObject *args) { xrequest->SetAttribute("message", message); doc.LinkEndChild(decl); doc.LinkEndChild(xrequest); + nout << "sending " << doc << "\n" << flush; _pipe_write << doc << flush; } else { diff --git a/direct/src/plugin/p3dSession.cxx b/direct/src/plugin/p3dSession.cxx index 0c2a05daef..6e6166f3b4 100644 --- a/direct/src/plugin/p3dSession.cxx +++ b/direct/src/plugin/p3dSession.cxx @@ -15,20 +15,12 @@ #include "p3dSession.h" #include "p3dInstance.h" #include "p3dInstanceManager.h" -#include "p3dProgressWindow.h" -#include "p3dWinProgressWindow.h" #include "p3d_plugin_config.h" #ifndef _WIN32 #include #endif -#ifdef _WIN32 -typedef P3DWinProgressWindow ProgressWindowType; -#else -typedef P3DProgressWindow ProgressWindowType; -#endif - //////////////////////////////////////////////////////////////////// // Function: P3DSession::Constructor // Access: Public @@ -161,23 +153,7 @@ start_instance(P3DInstance *inst) { } else { // Otherwise, set a callback, so we'll know when it is ready. if (_panda3d_callback == NULL) { - - _panda3d_callback = new P3DProgressWindow(_panda3d, this, inst); - - /* - // The callback object will be a ProgressWindow, to show - // visual progress to the user while we're downloading. - if (inst->get_window_type() == P3D_WT_hidden) { - // For a hidden window, just create an instance of the base - // class, which manifests no actual window. - _panda3d_callback = new P3DProgressWindow(_panda3d, this, inst); - } else { - // For a non-hidden window, create an instance of - // ProgressWindowType, which is typedeffed above to be the kind - // of class that actually does manifest a window. - _panda3d_callback = new ProgressWindowType(_panda3d, this, inst); - } - */ + _panda3d_callback = new PackageCallback(this); _panda3d->set_callback(_panda3d_callback); } } @@ -234,6 +210,20 @@ send_command(TiXmlDocument *command) { } } +//////////////////////////////////////////////////////////////////// +// Function: P3DSession::install_progress +// Access: Private +// Description: Notified as the _panda3d package is downloaded. +//////////////////////////////////////////////////////////////////// +void P3DSession:: +install_progress(P3DPackage *package, double progress) { + Instances::iterator ii; + for (ii = _instances.begin(); ii != _instances.end(); ++ii) { + P3DInstance *inst = (*ii).second; + inst->install_progress(package, progress); + } +} + //////////////////////////////////////////////////////////////////// // Function: P3DSession::start_p3dpython // Access: Private @@ -712,3 +702,51 @@ posix_create_process(const string &program, const string &start_dir, } #endif // _WIN32 + +//////////////////////////////////////////////////////////////////// +// Function: P3DSession::PackageCallback::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +P3DSession::PackageCallback:: +PackageCallback(P3DSession *session) : + _session(session) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DSession::PackageCallback::package_ready +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +void P3DSession::PackageCallback:: +package_ready(P3DPackage *package, bool success) { + if (this == _session->_panda3d_callback) { + _session->_panda3d_callback = NULL; + if (package == _session->_panda3d) { + if (success) { + _session->start_p3dpython(); + } else { + nout << "Failed to install " << package->get_package_name() + << "_" << package->get_package_version() << "\n"; + } + } else { + nout << "Unexpected panda3d package: " << package << "\n"; + } + } else { + nout << "Unexpected callback for P3DSession\n"; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DSession::PackageCallback::install_progress +// Access: Public, Virtual +// Description: This callback is received during the download process +// to inform us how much has been installed so far. +//////////////////////////////////////////////////////////////////// +void P3DSession::PackageCallback:: +install_progress(P3DPackage *package, double progress) { + if (this == _session->_panda3d_callback) { + _session->install_progress(package, progress); + } +} diff --git a/direct/src/plugin/p3dSession.h b/direct/src/plugin/p3dSession.h index a4413d4402..abbc3c833c 100644 --- a/direct/src/plugin/p3dSession.h +++ b/direct/src/plugin/p3dSession.h @@ -49,6 +49,7 @@ public: void send_command(TiXmlDocument *command); private: + void install_progress(P3DPackage *package, double progress); void start_p3dpython(); void spawn_read_thread(); @@ -79,6 +80,17 @@ private: HandleStream &pipe_read, HandleStream &pipe_write); #endif + class PackageCallback : public P3DPackage::Callback { + public: + PackageCallback(P3DSession *session); + + virtual void install_progress(P3DPackage *package, double progress); + virtual void package_ready(P3DPackage *package, bool success); + + protected: + P3DSession *_session; + }; + private: string _session_key; string _python_version; @@ -97,7 +109,7 @@ private: Commands _commands; P3DPackage *_panda3d; - P3DProgressWindow *_panda3d_callback; + PackageCallback *_panda3d_callback; // Members for communicating with the p3dpython child process. #ifdef _WIN32 @@ -119,7 +131,7 @@ private: pthread_t _read_thread; #endif - friend class P3DProgressWindow; + friend class PackageCallback; }; #include "p3dSession.I" diff --git a/direct/src/plugin/p3dSplashWindow.cxx b/direct/src/plugin/p3dSplashWindow.cxx index 12cdaf87d1..9049f9efed 100755 --- a/direct/src/plugin/p3dSplashWindow.cxx +++ b/direct/src/plugin/p3dSplashWindow.cxx @@ -17,7 +17,9 @@ //////////////////////////////////////////////////////////////////// // Function: P3DSplashWindow::Constructor // Access: Public -// Description: +// Description: By the time the SplashWindow is created, the instance +// has received both its fparams and its wparams. Copy +// them both into this class for reference. //////////////////////////////////////////////////////////////////// P3DSplashWindow:: P3DSplashWindow(P3DInstance *inst) : @@ -36,16 +38,6 @@ P3DSplashWindow:: ~P3DSplashWindow() { } -//////////////////////////////////////////////////////////////////// -// Function: P3DSplashWindow::set_fparams -// Access: Public, Virtual -// Description: Sets up the file parameters for the window. -//////////////////////////////////////////////////////////////////// -void P3DSplashWindow:: -set_fparams(const P3DFileParams &fparams) { - _fparams = fparams; -} - //////////////////////////////////////////////////////////////////// // Function: P3DSplashWindow::set_wparams // Access: Public, Virtual @@ -59,21 +51,21 @@ set_wparams(const P3DWindowParams &wparams) { } //////////////////////////////////////////////////////////////////// -// Function: P3DSplashWindow::open_window +// Function: P3DSplashWindow::set_install_label // Access: Public, Virtual -// Description: Creates the splash window. +// Description: Specifies the text that is displayed above the +// install progress bar. //////////////////////////////////////////////////////////////////// void P3DSplashWindow:: -open_window() { - nout << "P3DSplashWindow::open_window()\n" << flush; +set_install_label(const string &install_label) { } //////////////////////////////////////////////////////////////////// -// Function: P3DSplashWindow::close_window +// Function: P3DSplashWindow::set_install_progress // Access: Public, Virtual -// Description: Closes the window created above. +// Description: Moves the install progress bar from 0.0 to 1.0. //////////////////////////////////////////////////////////////////// void P3DSplashWindow:: -close_window() { - nout << "P3DSplashWindow::close_window()\n" << flush; +set_install_progress(double install_progress) { } + diff --git a/direct/src/plugin/p3dSplashWindow.h b/direct/src/plugin/p3dSplashWindow.h index 9637528a5d..cec6122367 100755 --- a/direct/src/plugin/p3dSplashWindow.h +++ b/direct/src/plugin/p3dSplashWindow.h @@ -37,14 +37,13 @@ public: P3DSplashWindow(P3DInstance *inst); virtual ~P3DSplashWindow(); - virtual void set_fparams(const P3DFileParams &fparams); inline const P3DFileParams &get_fparams() const; virtual void set_wparams(const P3DWindowParams &wparams); inline const P3DWindowParams &get_wparams() const; - virtual void open_window(); - virtual void close_window(); + virtual void set_install_label(const string &install_label); + virtual void set_install_progress(double install_progress); protected: P3DInstance *_inst; diff --git a/direct/src/plugin/p3dWinProgressWindow.I b/direct/src/plugin/p3dWinProgressWindow.I deleted file mode 100755 index 3ea98d9018..0000000000 --- a/direct/src/plugin/p3dWinProgressWindow.I +++ /dev/null @@ -1,14 +0,0 @@ -// Filename: p3dWinProgressWindow.I -// Created by: drose (17Jun09) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised BSD -// license. You should have received a copy of this license along -// with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// - diff --git a/direct/src/plugin/p3dWinProgressWindow.cxx b/direct/src/plugin/p3dWinProgressWindow.cxx deleted file mode 100755 index 4aeba97a33..0000000000 --- a/direct/src/plugin/p3dWinProgressWindow.cxx +++ /dev/null @@ -1,354 +0,0 @@ -// Filename: p3dWinProgressWindow.cxx -// Created by: drose (17Jun09) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised BSD -// license. You should have received a copy of this license along -// with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// - -#include "p3dWinProgressWindow.h" - -#ifdef _WIN32 - -//////////////////////////////////////////////////////////////////// -// Function: P3DWinProgressWindow::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -P3DWinProgressWindow:: -P3DWinProgressWindow(P3DPackage *package, P3DSession *session, - P3DInstance *inst) : - P3DProgressWindow(package, session, inst) -{ - _thread = NULL; - _hwnd = NULL; - _progress_bar = NULL; - _thread_running = false; - - INIT_LOCK(_progress_lock); - - assert(_wparams.get_window_type() != P3D_WT_hidden); - start_thread(); -} - -//////////////////////////////////////////////////////////////////// -// Function: P3DWinProgressWindow::Destructor -// Access: Public, Virtual -// Description: -//////////////////////////////////////////////////////////////////// -P3DWinProgressWindow:: -~P3DWinProgressWindow() { - stop_thread(); - - DESTROY_LOCK(_progress_lock); -} - -//////////////////////////////////////////////////////////////////// -// Function: P3DWinProgressWindow::install_progress -// Access: Public, Virtual -// Description: This callback is received during the download process -// to inform us how much has been installed so far. -//////////////////////////////////////////////////////////////////// -void P3DWinProgressWindow:: -install_progress(P3DPackage *package, double progress) { - P3DProgressWindow::install_progress(package, progress); - - ACQUIRE_LOCK(_progress_lock); - _progress = progress; - RELEASE_LOCK(_progress_lock); - - // Post a silly message to spin the message loop. - PostThreadMessage(_thread_id, WM_USER, 0, 0); - - if (!_thread_running) { - _inst->request_stop(); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: P3DWinProgressWindow::start_thraed -// Access: Private -// Description: Spawns the sub-thread. -//////////////////////////////////////////////////////////////////// -void P3DWinProgressWindow:: -start_thread() { - _thread_continue = true; - _thread = CreateThread(NULL, 0, &win_thread_run, this, 0, &_thread_id); - if (_thread != NULL) { - _thread_running = true; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: P3DWinProgressWindow::stop_thraed -// Access: Private -// Description: Terminates and joins the sub-thread. -//////////////////////////////////////////////////////////////////// -void P3DWinProgressWindow:: -stop_thread() { - _thread_continue = false; - // Post a silly message to spin the message loop. - PostThreadMessage(_thread_id, WM_USER, 0, 0); - - WaitForSingleObject(_thread, INFINITE); - CloseHandle(_thread); - _thread = NULL; -} - -//////////////////////////////////////////////////////////////////// -// Function: P3DWinProgressWindow::thread_run -// Access: Private -// Description: The sub-thread's main run method. -//////////////////////////////////////////////////////////////////// -void P3DWinProgressWindow:: -thread_run() { - make_window(); - - double last_progress = -1.0; - - _loop_started = GetTickCount(); - MSG msg; - int retval; - retval = GetMessage(&msg, NULL, 0, 0); - while (retval != 0 && _thread_continue) { - if (retval == -1) { - nout << "Error processing message queue.\n"; - break; - } - TranslateMessage(&msg); - DispatchMessage(&msg); - - { - ACQUIRE_LOCK(_progress_lock); - double new_progress = _progress; - RELEASE_LOCK(_progress_lock); - - if (new_progress != last_progress) { - if (_progress_bar == NULL) { - // Is it time to create the progress bar? - int now = GetTickCount(); - if (now - _loop_started > 2000) { - make_progress_bar(); - } - } else { - // Update the progress bar. We do this only within the - // thread, to ensure we don't get a race condition when - // starting or closing the thread. - SendMessage(_progress_bar, PBM_SETPOS, (int)(new_progress * 100.0), 0); - - last_progress = new_progress; - } - } - } - - retval = GetMessage(&msg, NULL, 0, 0); - } - - close_window(); - _thread_running = false; -} - -//////////////////////////////////////////////////////////////////// -// Function: P3DWinProgressWindow::win_thread_run -// Access: Private, Static -// Description: The OS-specific thread callback function. -//////////////////////////////////////////////////////////////////// -DWORD P3DWinProgressWindow:: -win_thread_run(LPVOID data) { - ((P3DWinProgressWindow *)data)->thread_run(); - return 0; -} - -//////////////////////////////////////////////////////////////////// -// Function: P3DWinProgressWindow::make_window -// Access: Private -// Description: Creates the window for displaying progress. Runs -// within the sub-thread. -//////////////////////////////////////////////////////////////////// -void P3DWinProgressWindow:: -make_window() { - WNDCLASS wc; - - HINSTANCE application = GetModuleHandle(NULL); - - static bool registered_class = false; - if (!registered_class) { - ZeroMemory(&wc, sizeof(WNDCLASS)); - wc.lpfnWndProc = window_proc; - wc.hInstance = application; - wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); - wc.lpszClassName = "panda3d_progress"; - - if (!RegisterClass(&wc)) { - nout << "Could not register window class!\n"; - } - registered_class = true; - } - - int x = CW_USEDEFAULT; - int y = CW_USEDEFAULT; - if (_wparams.get_win_x() != 0 && _wparams.get_win_y() != 0) { - x = _wparams.get_win_x(); - y = _wparams.get_win_y(); - } - - int width = 320; - int height = 240; - if (_wparams.get_win_width() != 0 && _wparams.get_win_height() != 0) { - width = _wparams.get_win_width(); - height = _wparams.get_win_height(); - } - - if (_wparams.get_window_type() == P3D_WT_embedded) { - // Create an embedded window. - DWORD window_style = - WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; - - HWND parent_hwnd = _wparams.get_parent_window()._hwnd; - - _hwnd = - CreateWindow("panda3d_progress", "Panda3D", window_style, - x, y, width, height, - parent_hwnd, NULL, application, 0); - - if (!_hwnd) { - nout << "Could not create embedded window!\n"; - return; - } - - } else { - // Create a toplevel window. - DWORD window_style = - WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | - WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | - WS_SIZEBOX | WS_MAXIMIZEBOX; - - _hwnd = - CreateWindow("panda3d_progress", "Panda3D", window_style, - x, y, width, height, - NULL, NULL, application, 0); - if (!_hwnd) { - nout << "Could not create toplevel window!\n"; - return; - } - - // We don't initially show the toplevel window. We'll show it - // when we create the actual progress bar, a few seconds later; - // otherwise, it might be distracting if the window pops up and - // then immediately disappears. - } -} - - -//////////////////////////////////////////////////////////////////// -// Function: P3DWinProgressWindow::make_progress_bar -// Access: Private -// Description: Creates the progress bar and label. Runs -// within the sub-thread. This is done a few seconds -// after the main window is created, to give us a chance -// to launch quickly without bothering the user. -//////////////////////////////////////////////////////////////////// -void P3DWinProgressWindow:: -make_progress_bar() { - if (_progress_bar != NULL) { - return; - } - - HINSTANCE application = GetModuleHandle(NULL); - DWORD window_style = - WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; - - RECT rect; - GetClientRect(_hwnd, &rect); - int width = rect.right - rect.left; - int height = rect.bottom - rect.top; - - int bar_width = min((int)(width * 0.6), 400); - int bar_height = min((int)(height * 0.1), 24); - int bar_x = (width - bar_width) / 2; - int bar_y = (height - bar_height) / 2; - - _progress_bar = - CreateWindowEx(0, PROGRESS_CLASS, "", window_style, - bar_x, bar_y, bar_width, bar_height, - _hwnd, NULL, application, 0); - - // Create a static text label. What a major pain *this* is. - string text_string = "Installing " + _package->get_package_display_name(); - const char *text = text_string.c_str(); - HFONT font = (HFONT)GetStockObject(ANSI_VAR_FONT); - - HDC dc = GetDC(_hwnd); - SelectObject(dc, font); - SIZE text_size; - GetTextExtentPoint32(dc, text, strlen(text), &text_size); - ReleaseDC(_hwnd, dc); - - int text_width = text_size.cx; - int text_height = text_size.cy; - int text_x = (width - text_width) / 2; - int text_y = bar_y - text_height - 2; - - CreateWindowEx(0, "STATIC", text, SS_OWNERDRAW | window_style, - text_x, text_y, text_width, text_height, - _hwnd, NULL, application, 0); - - // Ensure the main window is visible now. - ShowWindow(_hwnd, SW_SHOWNORMAL); -} - -//////////////////////////////////////////////////////////////////// -// Function: P3DWinProgressWindow::close_window -// Access: Private -// Description: Closes the window created above. -//////////////////////////////////////////////////////////////////// -void P3DWinProgressWindow:: -close_window() { - if (_hwnd) { - ShowWindow(_hwnd, SW_HIDE); - CloseWindow(_hwnd); - _hwnd = NULL; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: P3DWinProgressWindow::window_proc -// Access: Private, Static -// Description: The windows event-processing handler. -//////////////////////////////////////////////////////////////////// -LONG P3DWinProgressWindow:: -window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { - switch (msg) { - case WM_DESTROY: - PostQuitMessage(0); - break; - - case WM_DRAWITEM: - { - DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lparam; - FillRect(dis->hDC, &(dis->rcItem), WHITE_BRUSH); - - static const int text_buffer_size = 512; - char text_buffer[text_buffer_size]; - GetWindowText(dis->hwndItem, text_buffer, text_buffer_size); - - HFONT font = (HFONT)GetStockObject(ANSI_VAR_FONT); - SelectObject(dis->hDC, font); - SetBkColor(dis->hDC, 0x00ffffff); - - DrawText(dis->hDC, text_buffer, -1, &(dis->rcItem), - DT_BOTTOM | DT_CENTER | DT_SINGLELINE); - } - }; - - return DefWindowProc(hwnd, msg, wparam, lparam); -} - - -#endif // _WIN32 diff --git a/direct/src/plugin/p3dWinProgressWindow.h b/direct/src/plugin/p3dWinProgressWindow.h deleted file mode 100755 index 1e4d6e3bb2..0000000000 --- a/direct/src/plugin/p3dWinProgressWindow.h +++ /dev/null @@ -1,72 +0,0 @@ -// Filename: p3dWinProgressWindow.h -// Created by: drose (17Jun09) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) Carnegie Mellon University. All rights reserved. -// -// All use of this software is subject to the terms of the revised BSD -// license. You should have received a copy of this license along -// with this source code in a file named "LICENSE." -// -//////////////////////////////////////////////////////////////////// - -#ifndef P3DWINPROGRESSWINDOW_H -#define P3DWINPROGRESSWINDOW_H - -#include "p3d_plugin_common.h" - -#ifdef _WIN32 - -#include "p3dProgressWindow.h" -#include "p3d_lock.h" - -#include - -//////////////////////////////////////////////////////////////////// -// Class : P3DWinProgressWindow -// Description : This is the Windows implementation of the -// initial-download window. -//////////////////////////////////////////////////////////////////// -class P3DWinProgressWindow : public P3DProgressWindow { -public: - P3DWinProgressWindow(P3DPackage *package, P3DSession *session, P3DInstance *inst); - virtual ~P3DWinProgressWindow(); - -protected: - virtual void install_progress(P3DPackage *package, double progress); - -private: - void start_thread(); - void stop_thread(); - -private: - // These methods run only within the window thread. - void thread_run(); - static DWORD WINAPI win_thread_run(LPVOID data); - - void make_window(); - void make_progress_bar(); - void close_window(); - - static LONG WINAPI window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); - -private: - double _progress; - LOCK _progress_lock; - int _loop_started; - - bool _thread_continue; - bool _thread_running; - HANDLE _thread; - DWORD _thread_id; - HWND _hwnd; - HWND _progress_bar; -}; - -#include "p3dWinProgressWindow.I" - -#endif // _WIN32 - -#endif diff --git a/direct/src/plugin/p3dWinSplashWindow.cxx b/direct/src/plugin/p3dWinSplashWindow.cxx index 2be6ce586f..c4af338912 100755 --- a/direct/src/plugin/p3dWinSplashWindow.cxx +++ b/direct/src/plugin/p3dWinSplashWindow.cxx @@ -25,7 +25,19 @@ P3DWinSplashWindow:: P3DWinSplashWindow(P3DInstance *inst) : P3DSplashWindow(inst) { + _thread = NULL; + _thread_id = 0; _hwnd = NULL; + _progress_bar = NULL; + _text_label = NULL; + _thread_running = false; + _got_install = false; + _install_progress = 0.0; + _install_label_changed = false; + + INIT_LOCK(_install_lock); + + start_thread(); } //////////////////////////////////////////////////////////////////// @@ -35,17 +47,165 @@ P3DWinSplashWindow(P3DInstance *inst) : //////////////////////////////////////////////////////////////////// P3DWinSplashWindow:: ~P3DWinSplashWindow() { - close_window(); + stop_thread(); + + DESTROY_LOCK(_install_lock); } //////////////////////////////////////////////////////////////////// -// Function: P3DWinSplashWindow::open_window +// Function: P3DWinSplashWindow::set_install_label // Access: Public, Virtual -// Description: Creates the splash window. +// Description: Specifies the text that is displayed above the +// install progress bar. //////////////////////////////////////////////////////////////////// void P3DWinSplashWindow:: -open_window() { - P3DSplashWindow::open_window(); +set_install_label(const string &install_label) { + ACQUIRE_LOCK(_install_lock); + if (_install_label != install_label) { + _install_label = install_label; + _install_label_changed = true; + } + RELEASE_LOCK(_install_lock); + + // Post a silly message to spin the message loop. + PostThreadMessage(_thread_id, WM_USER, 0, 0); + + if (!_thread_running && _thread_continue) { + // The user must have closed the window. Let's shut down the + // instance, too. + _inst->request_stop(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DWinSplashWindow::set_install_progress +// Access: Public, Virtual +// Description: Moves the install progress bar from 0.0 to 1.0. +//////////////////////////////////////////////////////////////////// +void P3DWinSplashWindow:: +set_install_progress(double install_progress) { + _got_install = true; + + ACQUIRE_LOCK(_install_lock); + _install_progress = install_progress; + RELEASE_LOCK(_install_lock); + + // Post a silly message to spin the message loop. + PostThreadMessage(_thread_id, WM_USER, 0, 0); + + if (!_thread_running && _thread_continue) { + // The user must have closed the window. Let's shut down the + // instance, too. + _inst->request_stop(); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DWinSplashWindow::start_thraed +// Access: Private +// Description: Spawns the sub-thread. +//////////////////////////////////////////////////////////////////// +void P3DWinSplashWindow:: +start_thread() { + _thread_continue = true; + _thread = CreateThread(NULL, 0, &win_thread_run, this, 0, &_thread_id); + if (_thread != NULL) { + _thread_running = true; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DWinSplashWindow::stop_thraed +// Access: Private +// Description: Terminates and joins the sub-thread. +//////////////////////////////////////////////////////////////////// +void P3DWinSplashWindow:: +stop_thread() { + _thread_continue = false; + // Post a silly message to spin the message loop. + PostThreadMessage(_thread_id, WM_USER, 0, 0); + + WaitForSingleObject(_thread, INFINITE); + CloseHandle(_thread); + _thread = NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DWinSplashWindow::thread_run +// Access: Private +// Description: The sub-thread's main run method. +//////////////////////////////////////////////////////////////////// +void P3DWinSplashWindow:: +thread_run() { + make_window(); + + double last_progress = -1.0; + + _loop_started = GetTickCount(); + MSG msg; + int retval; + retval = GetMessage(&msg, NULL, 0, 0); + while (retval != 0 && _thread_continue) { + if (retval == -1) { + nout << "Error processing message queue.\n"; + break; + } + TranslateMessage(&msg); + DispatchMessage(&msg); + + if (_got_install) { + ACQUIRE_LOCK(_install_lock); + double install_progress = _install_progress; + if (_install_label_changed && _progress_bar != NULL) { + update_install_label(_install_label); + } + _install_label_changed = false; + RELEASE_LOCK(_install_lock); + + if (install_progress != last_progress) { + if (_progress_bar == NULL) { + // Is it time to create the progress bar? + int now = GetTickCount(); + if (now - _loop_started > 2000) { + make_progress_bar(); + } + } else { + // Update the progress bar. We do this only within the + // thread, to ensure we don't get a race condition when + // starting or closing the thread. + SendMessage(_progress_bar, PBM_SETPOS, (int)(install_progress * 100.0), 0); + + last_progress = install_progress; + } + } + } + + retval = GetMessage(&msg, NULL, 0, 0); + } + + close_window(); + _thread_running = false; +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DWinSplashWindow::win_thread_run +// Access: Private, Static +// Description: The OS-specific thread callback function. +//////////////////////////////////////////////////////////////////// +DWORD P3DWinSplashWindow:: +win_thread_run(LPVOID data) { + ((P3DWinSplashWindow *)data)->thread_run(); + return 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DWinSplashWindow::make_window +// Access: Private +// Description: Creates the window for displaying progress. Runs +// within the sub-thread. +//////////////////////////////////////////////////////////////////// +void P3DWinSplashWindow:: +make_window() { WNDCLASS wc; HINSTANCE application = GetModuleHandle(NULL); @@ -55,7 +215,7 @@ open_window() { ZeroMemory(&wc, sizeof(WNDCLASS)); wc.lpfnWndProc = window_proc; wc.hInstance = application; - wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszClassName = "panda3d_splash"; if (!RegisterClass(&wc)) { @@ -110,21 +270,117 @@ open_window() { nout << "Could not create toplevel window!\n"; return; } + ShowWindow(_hwnd, SW_SHOWNORMAL); } } - // Ensure the main window is visible now. + +//////////////////////////////////////////////////////////////////// +// Function: P3DWinSplashWindow::make_progress_bar +// Access: Private +// Description: Creates the progress bar and label. Runs +// within the sub-thread. This is done a few seconds +// after the main window is created, to give us a chance +// to launch quickly without bothering the user. +//////////////////////////////////////////////////////////////////// +void P3DWinSplashWindow:: +make_progress_bar() { + if (_progress_bar != NULL) { + return; + } + + ACQUIRE_LOCK(_install_lock); + string install_label = _install_label; + double install_progress = _install_progress; + _install_label_changed = false; + RELEASE_LOCK(_install_lock); + + HINSTANCE application = GetModuleHandle(NULL); + DWORD window_style = + WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + + RECT rect; + GetClientRect(_hwnd, &rect); + int width = rect.right - rect.left; + int height = rect.bottom - rect.top; + + int bar_width = min((int)(width * 0.6), 400); + int bar_height = min((int)(height * 0.1), 24); + int bar_x = (width - bar_width) / 2; + int bar_y = (height - bar_height) / 2; + + _progress_bar = + CreateWindowEx(0, PROGRESS_CLASS, "", window_style, + bar_x, bar_y, bar_width, bar_height, + _hwnd, NULL, application, 0); + SendMessage(_progress_bar, PBM_SETPOS, (int)(install_progress * 100.0), 0); + ShowWindow(_progress_bar, SW_SHOWNORMAL); + + update_install_label(install_label); +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DWinSplashWindow::update_install_label +// Access: Private +// Description: Changes the text on the install label. Runs within +// the sub-thread. +//////////////////////////////////////////////////////////////////// +void P3DWinSplashWindow:: +update_install_label(const string &install_label) { + assert(_progress_bar != NULL); + + if (_text_label != NULL) { + DestroyWindow(_text_label); + _text_label = NULL; + } + + if (install_label.empty()) { + // Trivial case. + return; + } + + // Create a static text label. What a major pain *this* is. + + const char *text = install_label.c_str(); + HFONT font = (HFONT)GetStockObject(ANSI_VAR_FONT); + + HDC dc = GetDC(_hwnd); + SelectObject(dc, font); + SIZE text_size; + GetTextExtentPoint32(dc, text, strlen(text), &text_size); + ReleaseDC(_hwnd, dc); + + HINSTANCE application = GetModuleHandle(NULL); + DWORD window_style = + SS_OWNERDRAW | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + + RECT rect; + GetClientRect(_hwnd, &rect); + int width = rect.right - rect.left; + int height = rect.bottom - rect.top; + + int bar_height = min((int)(height * 0.1), 24); + int bar_y = (height - bar_height) / 2; + + int text_width = text_size.cx; + int text_height = text_size.cy; + int text_x = (width - text_width) / 2; + int text_y = bar_y - text_height - 2; + + _text_label = CreateWindowEx(0, "STATIC", text, window_style, + text_x, text_y, text_width, text_height, + _hwnd, NULL, application, 0); + ShowWindow(_text_label, SW_SHOWNORMAL); } //////////////////////////////////////////////////////////////////// // Function: P3DWinSplashWindow::close_window -// Access: Public, Virtual +// Access: Private // Description: Closes the window created above. //////////////////////////////////////////////////////////////////// void P3DWinSplashWindow:: close_window() { - P3DSplashWindow::close_window(); if (_hwnd) { ShowWindow(_hwnd, SW_HIDE); CloseWindow(_hwnd); diff --git a/direct/src/plugin/p3dWinSplashWindow.h b/direct/src/plugin/p3dWinSplashWindow.h index 4ae0d8d5b5..b0aa08315b 100755 --- a/direct/src/plugin/p3dWinSplashWindow.h +++ b/direct/src/plugin/p3dWinSplashWindow.h @@ -34,14 +34,41 @@ public: P3DWinSplashWindow(P3DInstance *inst); virtual ~P3DWinSplashWindow(); - virtual void open_window(); - virtual void close_window(); + virtual void set_install_label(const string &install_label); + virtual void set_install_progress(double install_progress); private: + void start_thread(); + void stop_thread(); + +private: + // These methods run only within the window thread. + void thread_run(); + static DWORD WINAPI win_thread_run(LPVOID data); + + void make_window(); + void make_progress_bar(); + void update_install_label(const string &install_label); + void close_window(); + static LONG WINAPI window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); private: + bool _got_install; + bool _install_label_changed; + string _install_label; + double _install_progress; + LOCK _install_lock; + + int _loop_started; + + bool _thread_continue; + bool _thread_running; + HANDLE _thread; + DWORD _thread_id; HWND _hwnd; + HWND _progress_bar; + HWND _text_label; }; #include "p3dWinSplashWindow.I" diff --git a/direct/src/plugin/p3d_plugin_composite1.cxx b/direct/src/plugin/p3d_plugin_composite1.cxx index c9c4047784..6c234552e3 100644 --- a/direct/src/plugin/p3d_plugin_composite1.cxx +++ b/direct/src/plugin/p3d_plugin_composite1.cxx @@ -6,9 +6,7 @@ #include "p3dInstanceManager.cxx" #include "p3dMultifileReader.cxx" #include "p3dPackage.cxx" -#include "p3dProgressWindow.cxx" #include "p3dSplashWindow.cxx" #include "p3dSession.cxx" #include "p3dWindowParams.cxx" -#include "p3dWinProgressWindow.cxx" #include "p3dWinSplashWindow.cxx" diff --git a/direct/src/plugin_npapi/ppInstance.cxx b/direct/src/plugin_npapi/ppInstance.cxx index 3c10be4bac..946d80b69e 100644 --- a/direct/src/plugin_npapi/ppInstance.cxx +++ b/direct/src/plugin_npapi/ppInstance.cxx @@ -334,8 +334,9 @@ stream_as_file(NPStream *stream, const char *fname) { //////////////////////////////////////////////////////////////////// void PPInstance:: handle_request(P3D_request *request) { - logfile << "handle_request: " << request << ", " << request->_instance - << " within " << this << ", " << _p3d_inst << "\n" << flush; + logfile + << "handle_request: " << request << ", " << request->_request_type + << " within " << this << "\n" << flush; assert(request->_instance == _p3d_inst); bool handled = false; @@ -428,7 +429,13 @@ send_window() { P3D_window_handle parent_window; #ifdef _WIN32 - parent_window._hwnd = (HWND)(_window.window); + if (_window.type == NPWindowTypeWindow) { + parent_window._hwnd = (HWND)(_window.window); + } else { + // Hmm, it's just a drawable; but we didn't ask for a windowless + // plugin. + parent_window._hwnd = 0; + } #endif // Actually, we set up the window starting at (0, 0), instead of diff --git a/direct/src/plugin_npapi/startup.cxx b/direct/src/plugin_npapi/startup.cxx index 903f14b338..0e5c169f2b 100644 --- a/direct/src/plugin_npapi/startup.cxx +++ b/direct/src/plugin_npapi/startup.cxx @@ -34,9 +34,9 @@ open_logfile() { } #ifdef _WIN32 -UINT _timer = 0; +DWORD main_thread_id = 0; #endif -LOCK _timer_lock; + //////////////////////////////////////////////////////////////////// // Function: handle_request_loop @@ -45,44 +45,45 @@ LOCK _timer_lock; //////////////////////////////////////////////////////////////////// static void handle_request_loop() { - assert(is_plugin_loaded()); + if (!is_plugin_loaded()) { + return; + } - logfile << "about to call P3D_check_request()\n" << flush; P3D_instance *p3d_inst = P3D_check_request(false); - logfile << "P3D_check_request() returns " << p3d_inst << "\n" << flush; while (p3d_inst != (P3D_instance *)NULL) { P3D_request *request = P3D_instance_get_request(p3d_inst); - logfile << "got request " << request << "\n"; if (request != (P3D_request *)NULL) { PPInstance *inst = (PPInstance *)(p3d_inst->_user_data); assert(inst != NULL); inst->handle_request(request); } p3d_inst = P3D_check_request(false); - logfile << "P3D_check_request() returns " << p3d_inst << "\n" << flush; } } -//////////////////////////////////////////////////////////////////// -// Function: win_timer_func -// Description: The Windows flavor of the timer callback function. -//////////////////////////////////////////////////////////////////// #ifdef _WIN32 -static VOID CALLBACK -win_timer_func(HWND hwnd, UINT msg, UINT_PTR event, DWORD time) { - ACQUIRE_LOCK(_timer_lock); - logfile - << "win_timer_func " << hwnd << ", " << msg << ", " << event - << ", " << time << "\n" - << "timer thread = " << GetCurrentThreadId() << "\n" - << flush; - KillTimer(NULL, _timer); - _timer = 0; - RELEASE_LOCK(_timer_lock); +//////////////////////////////////////////////////////////////////// +// Function: window_proc +// Description: We bind this function to the parent windows we are +// given in NPP_New(), so we can spin the request_loop +// when needed. +//////////////////////////////////////////////////////////////////// +static LONG +window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { + // If this is a toplevel window event, but not something caused as a + // result of something done by handle_request_loop(), then call + // handle_request_loop() to see if there are any new requests to be + // forwarded to the main thread. + static int recursion_protect = 0; + ++recursion_protect; + if (recursion_protect == 1) { + handle_request_loop(); + } + --recursion_protect; - handle_request_loop(); + return DefWindowProc(hwnd, msg, wparam, lparam); } -#endif // _WIN32 +#endif // _WIN32 //////////////////////////////////////////////////////////////////// // Function: request_ready @@ -94,20 +95,15 @@ win_timer_func(HWND hwnd, UINT msg, UINT_PTR event, DWORD time) { void request_ready(P3D_instance *instance) { logfile - << "request_ready" - // << " thread = " << GetCurrentThreadId() + << "request_ready in " << instance + << " thread = " << GetCurrentThreadId() << "\n" << flush; - // Since we might be in a sub-thread at this point, use a timer to - // forward this event to the main thread. + // Since we might be in a sub-thread at this point, use a Windows + // message to forward this event to the main thread. #ifdef _WIN32 - ACQUIRE_LOCK(_timer_lock); - if (_timer == 0) { - _timer = SetTimer(NULL, 0, 0, win_timer_func); - logfile << "_timer = " << _timer << "\n" << flush; - } - RELEASE_LOCK(_timer_lock); + PostThreadMessage(main_thread_id, WM_USER, 0, 0); #else // TODO: send the message to the main thread properly. handle_request_loop(); @@ -139,12 +135,16 @@ NP_Initialize(NPNetscapeFuncs *browserFuncs, open_logfile(); logfile << "initializing\n" << flush; - // logfile << "main thread = " << GetCurrentThreadId() << "\n"; + +#ifdef _WIN32 + // Save the calling thread ID (i.e. the main thread) so we can post + // messages back to this thread when needed. + main_thread_id = GetCurrentThreadId(); + logfile << "main thread = " << main_thread_id << "\n"; +#endif logfile << "browserFuncs = " << browserFuncs << "\n" << flush; - INIT_LOCK(_timer_lock); - /* #ifdef _WIN32 string plugin_location = "c:/cygwin/home/drose/player/direct/built/lib/p3d_plugin.dll"; @@ -202,23 +202,8 @@ NP_GetEntryPoints(NPPluginFuncs *pluginFuncs) { NPError OSCALL NP_Shutdown(void) { logfile << "shutdown\n" << flush; - - ACQUIRE_LOCK(_timer_lock); -#ifdef _WIN32 - if (_timer != 0) { - KillTimer(NULL, _timer); - _timer = 0; - } -#endif - RELEASE_LOCK(_timer_lock); - DESTROY_LOCK(_timer_lock); - - logfile << "unloading plugin\n" << flush; - unload_plugin(); - logfile << "done shutdown\n" << flush; - // Not clear whether there's a return value or not. Some versions // of the API have different opinions on this. return NPERR_NO_ERROR; @@ -270,6 +255,14 @@ NPP_SetWindow(NPP instance, NPWindow *window) { << ", " << window->width << ", " << window->height << "\n" << flush; + if (window->type == NPWindowTypeWindow) { + // Subclass the window to make it call our own window_proc instead + // of whatever window_proc it has already. This is just a dopey + // trick to allow us to poll events in the main thread. + HWND hwnd = (HWND)window->window; + LONG_PTR orig = SetWindowLongPtr(hwnd, GWL_WNDPROC, (LONG_PTR)window_proc); + } + PPInstance *inst = (PPInstance *)(instance->pdata); assert(inst != NULL); inst->set_window(window); @@ -426,3 +419,4 @@ NPP_SetValue(NPP instance, NPNVariable variable, void *value) { logfile << "SetValue " << variable << "\n"; return NPERR_GENERIC_ERROR; } + diff --git a/direct/src/plugin_standalone/panda3d.cxx b/direct/src/plugin_standalone/panda3d.cxx index be8f95d7d2..7fe837065f 100644 --- a/direct/src/plugin_standalone/panda3d.cxx +++ b/direct/src/plugin_standalone/panda3d.cxx @@ -248,10 +248,11 @@ P3D_instance * create_instance(const string &arg, P3D_window_type window_type, int win_x, int win_y, int win_width, int win_height, P3D_window_handle parent_window, - const string &output_filename) { + const Filename &output_filename) { + string os_output_filename = output_filename.to_os_specific(); P3D_token tokens[] = { - { "output_filename", output_filename.c_str() }, + { "output_filename", os_output_filename.c_str() }, { "src", arg.c_str() }, }; int num_tokens = sizeof(tokens) / sizeof(P3D_token); @@ -343,8 +344,8 @@ int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { extern int optind; const char *optstr = "p:l:t:s:o:h"; - string p3d_plugin_filename; - string output_filename; + Filename p3d_plugin_filename; + Filename output_filename; P3D_window_type window_type = P3D_WT_toplevel; int win_x = 0, win_y = 0; int win_width = 0, win_height = 0; @@ -354,11 +355,11 @@ int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { while (flag != EOF) { switch (flag) { case 'p': - p3d_plugin_filename = optarg; + p3d_plugin_filename = Filename::from_os_specific(optarg); break; case 'l': - output_filename = optarg; + output_filename = Filename::from_os_specific(optarg); break; case 't': @@ -407,7 +408,7 @@ int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { return 1; } - if (!load_plugin(p3d_plugin_filename)) { + if (!load_plugin(p3d_plugin_filename.to_os_specific())) { cerr << "Unable to load Panda3D plugin.\n"; return 1; } diff --git a/direct/src/showutil/runp3d.py b/direct/src/showutil/runp3d.py index 487e0289e0..87ff680fe0 100755 --- a/direct/src/showutil/runp3d.py +++ b/direct/src/showutil/runp3d.py @@ -133,7 +133,6 @@ class AppRunner(DirectObject): # One day we will have support for multiple instances within a # Python session. Against that day, we save the instance ID # for this instance. - print "setP3DFilename(%s, %s, %s)" % (p3dFilename, tokens, instanceId) self.instanceId = instanceId tokenDict = dict(tokens)