浏览代码

progress bars are back

David Rose 16 年之前
父节点
当前提交
01ced75007

+ 0 - 4
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 \

+ 23 - 7
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);
+  }
+}

+ 2 - 2
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;

+ 0 - 14
direct/src/plugin/p3dProgressWindow.I

@@ -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."
-//
-////////////////////////////////////////////////////////////////////
-

+ 0 - 54
direct/src/plugin/p3dProgressWindow.cxx

@@ -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";
-  }
-}
-

+ 0 - 52
direct/src/plugin/p3dProgressWindow.h

@@ -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

+ 1 - 0
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 {

+ 63 - 25
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 <fcntl.h>
 #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);
+  }
+}

+ 14 - 2
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"

+ 11 - 19
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) {
 }
+

+ 2 - 3
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;

+ 0 - 14
direct/src/plugin/p3dWinProgressWindow.I

@@ -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."
-//
-////////////////////////////////////////////////////////////////////
-

+ 0 - 354
direct/src/plugin/p3dWinProgressWindow.cxx

@@ -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

+ 0 - 72
direct/src/plugin/p3dWinProgressWindow.h

@@ -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 <windows.h>
-
-////////////////////////////////////////////////////////////////////
-//       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

+ 265 - 9
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::set_install_label
+//       Access: Public, Virtual
+//  Description: Specifies the text that is displayed above the
+//               install progress bar.
+////////////////////////////////////////////////////////////////////
+void P3DWinSplashWindow::
+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::open_window
+//     Function: P3DWinSplashWindow::set_install_progress
 //       Access: Public, Virtual
-//  Description: Creates the splash window.
+//  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::
-open_window() {
-  P3DSplashWindow::open_window();
+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);

+ 29 - 2
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"

+ 0 - 2
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"

+ 10 - 3
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

+ 46 - 52
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,11 +135,15 @@ NP_Initialize(NPNetscapeFuncs *browserFuncs,
 
   open_logfile();
   logfile << "initializing\n" << flush;
-  //  logfile << "main thread = " << GetCurrentThreadId() << "\n";
 
-  logfile << "browserFuncs = " << browserFuncs << "\n" << flush;
+#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
 
-  INIT_LOCK(_timer_lock);
+  logfile << "browserFuncs = " << browserFuncs << "\n" << flush;
 
   /*
 #ifdef _WIN32
@@ -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;
 }
+

+ 8 - 7
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;
   }

+ 0 - 1
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)