From ec23ed2a43408f394fbd24938600bf0b4efe0d05 Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 24 Jun 2009 09:39:11 +0000 Subject: [PATCH] cleaner p3d scripts --- direct/src/plugin/Sources.pp | 8 +- direct/src/plugin/p3dInstance.cxx | 31 +++ direct/src/plugin/p3dInstance.h | 3 + direct/src/plugin/p3dPythonRun.cxx | 47 ++-- direct/src/plugin/p3dPythonRun.h | 3 +- direct/src/plugin/p3dSession.cxx | 8 +- direct/src/plugin/p3dSplashWindow.I | 34 +++ direct/src/plugin/p3dSplashWindow.cxx | 79 ++++++ direct/src/plugin/p3dSplashWindow.h | 57 ++++ direct/src/plugin/p3dWinSplashWindow.I | 14 + direct/src/plugin/p3dWinSplashWindow.cxx | 170 ++++++++++++ direct/src/plugin/p3dWinSplashWindow.h | 51 ++++ direct/src/plugin/p3d_plugin_composite1.cxx | 2 + direct/src/plugin_npapi/startup.cxx | 4 - direct/src/showbase/RunAppMF.py | 231 ---------------- direct/src/showutil/Sources.pp | 53 ++++ .../MakeAppMF.py => showutil/packp3d.py} | 22 +- direct/src/showutil/runp3d.py | 257 ++++++++++++++++++ 18 files changed, 806 insertions(+), 268 deletions(-) create mode 100755 direct/src/plugin/p3dSplashWindow.I create mode 100755 direct/src/plugin/p3dSplashWindow.cxx create mode 100755 direct/src/plugin/p3dSplashWindow.h create mode 100755 direct/src/plugin/p3dWinSplashWindow.I create mode 100755 direct/src/plugin/p3dWinSplashWindow.cxx create mode 100755 direct/src/plugin/p3dWinSplashWindow.h delete mode 100644 direct/src/showbase/RunAppMF.py rename direct/src/{showbase/MakeAppMF.py => showutil/packp3d.py} (96%) mode change 100644 => 100755 create mode 100755 direct/src/showutil/runp3d.py diff --git a/direct/src/plugin/Sources.pp b/direct/src/plugin/Sources.pp index 9cbde330ad..738b484deb 100644 --- a/direct/src/plugin/Sources.pp +++ b/direct/src/plugin/Sources.pp @@ -25,8 +25,10 @@ p3dPackage.h p3dPackage.I \ p3dProgressWindow.h p3dProgressWindow.I \ p3dSession.h p3dSession.I \ + p3dSplashWindow.h p3dSplashWindow.I \ p3dWindowParams.h p3dWindowParams.I \ - p3dWinProgressWindow.h p3dWinProgressWindow.I + p3dWinProgressWindow.h p3dWinProgressWindow.I \ + p3dWinSplashWindow.h p3dWinSplashWindow.I #define INCLUDED_SOURCES \ p3d_plugin.cxx \ @@ -38,9 +40,11 @@ p3dMultifileReader.cxx \ p3dPackage.cxx \ p3dProgressWindow.cxx \ + p3dSplashWindow.cxx \ p3dSession.cxx \ p3dWindowParams.cxx \ - p3dWinProgressWindow.cxx + p3dWinProgressWindow.cxx \ + p3dWinSplashWindow.cxx #define INSTALL_HEADERS \ p3d_plugin.h diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index efa0681dc1..37a94672e3 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -17,10 +17,18 @@ #include "p3dDownload.h" #include "p3dSession.h" #include "p3dPackage.h" +#include "p3dSplashWindow.h" +#include "p3dWinSplashWindow.h" #include #include +#ifdef _WIN32 +typedef P3DWinSplashWindow SplashWindowType; +#else +typedef P3DSplashWindow SplashWindowType; +#endif + int P3DInstance::_next_instance_id = 0; //////////////////////////////////////////////////////////////////// @@ -43,6 +51,8 @@ P3DInstance(P3D_request_ready_func *func, void *user_data) : INIT_LOCK(_request_lock); _session = NULL; + _splash_window = NULL; + _instance_window_opened = false; _requested_stop = false; } @@ -65,6 +75,11 @@ P3DInstance:: } _packages.clear(); + if (_splash_window != NULL) { + delete _splash_window; + _splash_window = NULL; + } + // TODO: empty _pending_requests queue and _downloads map. // TODO: Is it possible for someone to delete an instance while a @@ -82,6 +97,11 @@ set_fparams(const P3DFileParams &fparams) { _got_fparams = true; _fparams = fparams; + // Update the splash window. + if (_splash_window != NULL) { + _splash_window->set_fparams(_fparams); + } + // This also sets up some internal data based on the contents of the // above file and the associated tokens. @@ -106,6 +126,17 @@ set_wparams(const P3DWindowParams &wparams) { _got_wparams = true; _wparams = wparams; + // Update or create the splash window. + if (!_instance_window_opened) { + if (_splash_window == NULL) { + _splash_window = new SplashWindowType(this); + _splash_window->open_window(); + } else { + _splash_window->set_wparams(_wparams); + } + } + + // Update the instance in the sub-process. if (_session != NULL) { TiXmlDocument *doc = new TiXmlDocument; TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "", ""); diff --git a/direct/src/plugin/p3dInstance.h b/direct/src/plugin/p3dInstance.h index 70242a6ebc..b0e6841e07 100644 --- a/direct/src/plugin/p3dInstance.h +++ b/direct/src/plugin/p3dInstance.h @@ -25,6 +25,7 @@ #include class P3DSession; +class P3DSplashWindow; class P3DDownload; class P3DPackage; @@ -85,6 +86,8 @@ private: string _session_key; string _python_version; P3DSession *_session; + P3DSplashWindow *_splash_window; + bool _instance_window_opened; typedef vector Packages; Packages _packages; diff --git a/direct/src/plugin/p3dPythonRun.cxx b/direct/src/plugin/p3dPythonRun.cxx index 4a876cdf68..2d278f69d1 100755 --- a/direct/src/plugin/p3dPythonRun.cxx +++ b/direct/src/plugin/p3dPythonRun.cxx @@ -88,37 +88,46 @@ P3DPythonRun:: //////////////////////////////////////////////////////////////////// bool P3DPythonRun:: run_python() { - // Now load runappmf.pyd. - PyObject *runappmf = PyImport_ImportModule("runappmf"); - if (runappmf == NULL) { + // First, load runp3d_frozen.pyd. Since this is a magic frozen pyd, + // importing it automatically makes all of its frozen contents + // available to import as well. + PyObject *runp3d_frozen = PyImport_ImportModule("runp3d_frozen"); + if (runp3d_frozen == NULL) { PyErr_Print(); return false; } - Py_DECREF(runappmf); + Py_DECREF(runp3d_frozen); - // And get the pointers to the functions needed within the module. - PyObject *appmf = PyImport_ImportModule("direct.showbase.RunAppMF"); - if (appmf == NULL) { + // So now we can import the module itself. + PyObject *runp3d = PyImport_ImportModule("direct.showutil.runp3d"); + if (runp3d == NULL) { PyErr_Print(); return false; } - _setP3DFilename = PyObject_GetAttrString(appmf, "setP3DFilename"); - if (_setP3DFilename == NULL) { + + // Get the pointers to the objects needed within the module. + PyObject *AppRunner = PyObject_GetAttrString(runp3d, "AppRunner"); + if (AppRunner == NULL) { PyErr_Print(); return false; } - _setupWindow = PyObject_GetAttrString(appmf, "setupWindow"); - if (_setupWindow == NULL) { + + // Construct an instance of AppRunner. + _runner = PyObject_CallFunction(AppRunner, ""); + if (_runner == NULL) { PyErr_Print(); return false; } - _taskMgr = PyObject_GetAttrString(appmf, "taskMgr"); + Py_DECREF(AppRunner); + + // Get the global TaskManager. + _taskMgr = PyObject_GetAttrString(runp3d, "taskMgr"); if (_taskMgr == NULL) { PyErr_Print(); return false; } - Py_DECREF(appmf); + Py_DECREF(runp3d); // Now add check_comm() as a task. _check_comm_task = new GenericAsyncTask("check_comm", st_check_comm, this); @@ -359,8 +368,8 @@ set_p3d_filename(P3DCInstance *inst, TiXmlElement *xfparams) { xtoken = xtoken->NextSiblingElement("token"); } - PyObject *result = PyObject_CallFunction - (_setP3DFilename, "sO", p3d_filename.c_str(), token_list); + PyObject *result = PyObject_CallMethod + (_runner, "setP3DFilename", "sO", p3d_filename.c_str(), token_list); Py_DECREF(token_list); if (result == NULL) { @@ -415,10 +424,10 @@ setup_window(P3DCInstance *inst, TiXmlElement *xwparams) { } #endif - // TODO: direct this into the particular instance. Requires - // specialized ShowBase replacement. - PyObject *result = PyObject_CallFunction - (_setupWindow, "siiiii", window_type.c_str(), + // TODO: direct this into the particular instance. This will + // require a specialized ShowBase replacement. + PyObject *result = PyObject_CallMethod + (_runner, "setupWindow", "siiiii", window_type.c_str(), win_x, win_y, win_width, win_height, parent_window_handle); if (result == NULL) { diff --git a/direct/src/plugin/p3dPythonRun.h b/direct/src/plugin/p3dPythonRun.h index 31559c90a8..8580c6edeb 100755 --- a/direct/src/plugin/p3dPythonRun.h +++ b/direct/src/plugin/p3dPythonRun.h @@ -95,8 +95,7 @@ private: int _py_argc; char **_py_argv; - PyObject *_setP3DFilename; - PyObject *_setupWindow; + PyObject *_runner; PyObject *_taskMgr; PT(GenericAsyncTask) _check_comm_task; diff --git a/direct/src/plugin/p3dSession.cxx b/direct/src/plugin/p3dSession.cxx index 79098e9ec6..25444b87a6 100644 --- a/direct/src/plugin/p3dSession.cxx +++ b/direct/src/plugin/p3dSession.cxx @@ -24,9 +24,9 @@ #endif #ifdef _WIN32 -typedef P3DWinProgressWindow ProgressWinType; +typedef P3DWinProgressWindow ProgressWindowType; #else -typedef P3DProgressWindow ProgressWinType; +typedef P3DProgressWindow ProgressWindowType; #endif //////////////////////////////////////////////////////////////////// @@ -173,9 +173,9 @@ start_instance(P3DInstance *inst) { _panda3d_callback = new P3DProgressWindow(_panda3d, this, inst); } else { // For a non-hidden window, create an instance of - // ProgressWinType, which is typedeffed above to be the kind + // ProgressWindowType, which is typedeffed above to be the kind // of class that actually does manifest a window. - _panda3d_callback = new ProgressWinType(_panda3d, this, inst); + _panda3d_callback = new ProgressWindowType(_panda3d, this, inst); } */ _panda3d->set_callback(_panda3d_callback); diff --git a/direct/src/plugin/p3dSplashWindow.I b/direct/src/plugin/p3dSplashWindow.I new file mode 100755 index 0000000000..18cdd9fb43 --- /dev/null +++ b/direct/src/plugin/p3dSplashWindow.I @@ -0,0 +1,34 @@ +// Filename: p3dSplashWindow.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." +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: P3DSplashWindow::get_fparams +// Access: Public +// Description: Returns the current file parameters. +//////////////////////////////////////////////////////////////////// +inline const P3DFileParams &P3DSplashWindow:: +get_fparams() const { + return _fparams; +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DSplashWindow::get_wparams +// Access: Public +// Description: Returns the current window parameters. +//////////////////////////////////////////////////////////////////// +inline const P3DWindowParams &P3DSplashWindow:: +get_wparams() const { + return _wparams; +} diff --git a/direct/src/plugin/p3dSplashWindow.cxx b/direct/src/plugin/p3dSplashWindow.cxx new file mode 100755 index 0000000000..12cdaf87d1 --- /dev/null +++ b/direct/src/plugin/p3dSplashWindow.cxx @@ -0,0 +1,79 @@ +// Filename: p3dSplashWindow.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 "p3dSplashWindow.h" + +//////////////////////////////////////////////////////////////////// +// Function: P3DSplashWindow::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +P3DSplashWindow:: +P3DSplashWindow(P3DInstance *inst) : + _inst(inst), + _fparams(inst->get_fparams()), + _wparams(inst->get_wparams()) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DSplashWindow::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +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 +// Description: Changes the window parameters, e.g. to resize or +// reposition the window; or sets the parameters for the +// first time, creating the initial window. +//////////////////////////////////////////////////////////////////// +void P3DSplashWindow:: +set_wparams(const P3DWindowParams &wparams) { + _wparams = wparams; +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DSplashWindow::open_window +// Access: Public, Virtual +// Description: Creates the splash window. +//////////////////////////////////////////////////////////////////// +void P3DSplashWindow:: +open_window() { + nout << "P3DSplashWindow::open_window()\n" << flush; +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DSplashWindow::close_window +// Access: Public, Virtual +// Description: Closes the window created above. +//////////////////////////////////////////////////////////////////// +void P3DSplashWindow:: +close_window() { + nout << "P3DSplashWindow::close_window()\n" << flush; +} diff --git a/direct/src/plugin/p3dSplashWindow.h b/direct/src/plugin/p3dSplashWindow.h new file mode 100755 index 0000000000..9637528a5d --- /dev/null +++ b/direct/src/plugin/p3dSplashWindow.h @@ -0,0 +1,57 @@ +// Filename: p3dSplashWindow.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 P3DSPLASHWINDOW_H +#define P3DSPLASHWINDOW_H + +#include "p3d_plugin_common.h" +#include "p3dFileParams.h" +#include "p3dWindowParams.h" + +class P3DInstance; + +//////////////////////////////////////////////////////////////////// +// Class : P3DSplashWindow +// Description : This window is displayed temporarily, in place of an +// instance's actual window, during the initial launch +// of an applet, and also during the initial download of +// Panda3D code if necessary. +// +// This is the base implementation; it contains no +// specific code to open a window. +//////////////////////////////////////////////////////////////////// +class P3DSplashWindow { +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(); + +protected: + P3DInstance *_inst; + P3DFileParams _fparams; + P3DWindowParams _wparams; +}; + +#include "p3dSplashWindow.I" + +#endif diff --git a/direct/src/plugin/p3dWinSplashWindow.I b/direct/src/plugin/p3dWinSplashWindow.I new file mode 100755 index 0000000000..e144c6e755 --- /dev/null +++ b/direct/src/plugin/p3dWinSplashWindow.I @@ -0,0 +1,14 @@ +// Filename: p3dWinSplashWindow.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/p3dWinSplashWindow.cxx b/direct/src/plugin/p3dWinSplashWindow.cxx new file mode 100755 index 0000000000..2be6ce586f --- /dev/null +++ b/direct/src/plugin/p3dWinSplashWindow.cxx @@ -0,0 +1,170 @@ +// Filename: p3dWinSplashWindow.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 "p3dWinSplashWindow.h" + +#ifdef _WIN32 + +//////////////////////////////////////////////////////////////////// +// Function: P3DWinSplashWindow::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +P3DWinSplashWindow:: +P3DWinSplashWindow(P3DInstance *inst) : + P3DSplashWindow(inst) +{ + _hwnd = NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DWinSplashWindow::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +P3DWinSplashWindow:: +~P3DWinSplashWindow() { + close_window(); +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DWinSplashWindow::open_window +// Access: Public, Virtual +// Description: Creates the splash window. +//////////////////////////////////////////////////////////////////// +void P3DWinSplashWindow:: +open_window() { + P3DSplashWindow::open_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(BLACK_BRUSH); + wc.lpszClassName = "panda3d_splash"; + + 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_splash", "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_splash", "Panda3D", window_style, + x, y, width, height, + NULL, NULL, application, 0); + if (!_hwnd) { + nout << "Could not create toplevel window!\n"; + return; + } + ShowWindow(_hwnd, SW_SHOWNORMAL); + } +} + + // Ensure the main window is visible now. +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DWinSplashWindow::close_window +// Access: Public, Virtual +// Description: Closes the window created above. +//////////////////////////////////////////////////////////////////// +void P3DWinSplashWindow:: +close_window() { + P3DSplashWindow::close_window(); + if (_hwnd) { + ShowWindow(_hwnd, SW_HIDE); + CloseWindow(_hwnd); + _hwnd = NULL; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: P3DWinSplashWindow::window_proc +// Access: Private, Static +// Description: The windows event-processing handler. +//////////////////////////////////////////////////////////////////// +LONG P3DWinSplashWindow:: +window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { + switch (msg) { + case WM_DESTROY: + PostQuitMessage(0); + break; + + case WM_DRAWITEM: + // Draw a text label placed within the window. + { + 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/p3dWinSplashWindow.h b/direct/src/plugin/p3dWinSplashWindow.h new file mode 100755 index 0000000000..4ae0d8d5b5 --- /dev/null +++ b/direct/src/plugin/p3dWinSplashWindow.h @@ -0,0 +1,51 @@ +// Filename: p3dWinSplashWindow.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 P3DWINSPLASHWINDOW_H +#define P3DWINSPLASHWINDOW_H + +#include "p3d_plugin_common.h" + +#ifdef _WIN32 + +#include "p3dSplashWindow.h" +#include "p3d_lock.h" + +#include + +//////////////////////////////////////////////////////////////////// +// Class : P3DWinSplashWindow +// Description : This is the Windows implementation of the +// initial-download window. +//////////////////////////////////////////////////////////////////// +class P3DWinSplashWindow : public P3DSplashWindow { +public: + P3DWinSplashWindow(P3DInstance *inst); + virtual ~P3DWinSplashWindow(); + + virtual void open_window(); + virtual void close_window(); + +private: + static LONG WINAPI window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); + +private: + HWND _hwnd; +}; + +#include "p3dWinSplashWindow.I" + +#endif // _WIN32 + +#endif diff --git a/direct/src/plugin/p3d_plugin_composite1.cxx b/direct/src/plugin/p3d_plugin_composite1.cxx index f9fa2dca50..c9c4047784 100644 --- a/direct/src/plugin/p3d_plugin_composite1.cxx +++ b/direct/src/plugin/p3d_plugin_composite1.cxx @@ -7,6 +7,8 @@ #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/startup.cxx b/direct/src/plugin_npapi/startup.cxx index 5f6b30bb1b..903f14b338 100644 --- a/direct/src/plugin_npapi/startup.cxx +++ b/direct/src/plugin_npapi/startup.cxx @@ -324,7 +324,6 @@ NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason) { //////////////////////////////////////////////////////////////////// int32 NPP_WriteReady(NPP instance, NPStream *stream) { - logfile << "WriteReady\n"; // We're supposed to return the maximum amount of data the plugin is // prepared to handle. Gee, I don't know. As much as you can give // me, I guess. @@ -340,9 +339,6 @@ NPP_WriteReady(NPP instance, NPStream *stream) { int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer) { - logfile << "Write " << stream->url - << ", " << len << "\n" << flush; - PPInstance *inst = (PPInstance *)(instance->pdata); assert(inst != NULL); diff --git a/direct/src/showbase/RunAppMF.py b/direct/src/showbase/RunAppMF.py deleted file mode 100644 index c51c70fe91..0000000000 --- a/direct/src/showbase/RunAppMF.py +++ /dev/null @@ -1,231 +0,0 @@ -""" This module can serve as a startup script to play a Panda -application packed within a .mf file. Run via: - -python RunAppMF.py app.mf - -This is currently experimental, but the intent is to work towards a -prepackaged Panda distributable, designed to run applications exactly -like this. - -Also see MakeAppMF.py. - -""" - -import sys -from direct.showbase import VFSImporter -from pandac.PandaModules import VirtualFileSystem, Filename, Multifile, loadPrcFileData, getModelPath, HTTPClient -from direct.stdpy import file -from direct.task.TaskManagerGlobal import taskMgr -import os -import __builtin__ - -MultifileRoot = '/mf' - -# This defines the default prc file that is implicitly loaded with an -# application. -AppPrcFilename = 'App.prc' -AppPrc = """ -default-model-extension .bam -""" - -class ArgumentError(AttributeError): - pass - -__packedAppEnvironmentInitialized = False - -def initPackedAppEnvironment(): - """ This function sets up the Python environment suitably for - running a packed app. It should only run once in any given - session (and it includes logic to ensure this). """ - - global __packedAppEnvironmentInitialized - if __packedAppEnvironmentInitialized: - return - - __packedAppEnvironmentInitialized = True - - # We need to make sure sys.stdout maps to sys.stderr instead, so - # if someone makes an unadorned print command within Python code, - # it won't muck up the data stream between parent and child. - sys.stdout = sys.stderr - - vfs = VirtualFileSystem.getGlobalPtr() - - # Clear *all* the mount points, including "/", so that we no - # longer access the disk directly. - vfs.unmountAll() - - # Make sure the directories on our standard Python path are mounted - # read-only, so we can still load Python. - for dirname in sys.path: - vfs.mount(dirname, dirname, vfs.MFReadOnly) - - # Also mount some standard directories read-write (temporary and - # app-data directories). - tdir = Filename.temporary('', '') - for dirname in set([ tdir.getDirname(), - Filename.getTempDirectory().cStr(), - Filename.getUserAppdataDirectory().cStr(), - Filename.getCommonAppdataDirectory().cStr() ]): - vfs.mount(dirname, dirname, 0) - - # Now set up Python to import this stuff. - VFSImporter.register() - sys.path = [ MultifileRoot ] + sys.path - - # Put our root directory on the model-path and prc-path, too. - getModelPath().prependDirectory(MultifileRoot) - - # Load the implicit App.prc file. - loadPrcFileData(AppPrcFilename, AppPrc) - - # Replace the builtin open and file symbols so user code will get - # our versions by default, which can open and read files out of - # the multifile. - __builtin__.file = file.file - __builtin__.open = file.open - os.listdir = file.listdir - os.walk = file.walk - - # Make "/mf" our "current directory", for running the multifiles - # we plan to mount there. - vfs.chdir(MultifileRoot) - -gotWindow = False -gotP3DFilename = False -started = False -def startIfReady(): - global gotWindow, gotP3DFilename, started - if started: - return - - if gotWindow and gotP3DFilename: - started = True - import main - if hasattr(main, 'main') and callable(main.main): - main.main() - -def setP3DFilename(p3dFilename, tokens = []): - tokenDict = dict(tokens) - fname = Filename.fromOsSpecific(p3dFilename) - if not p3dFilename: - # If we didn't get a literal filename, we have to download it - # from the URL. TODO: make this a smarter temporary filename? - fname = Filename.temporary('', 'p3d_') - fname.setExtension('p3d') - p3dFilename = fname.toOsSpecific() - src = tokenDict.get('src', None) - if not src: - raise ArgumentError, "No Panda app specified." - - http = HTTPClient.getGlobalPtr() - hc = http.getDocument(src) - if not hc.downloadToFile(fname): - fname.unlink() - raise ArgumentError, "Couldn't download %s" % (src) - - # Set a hook on sys.exit to delete the temporary file. - oldexitfunc = getattr(sys, 'exitfunc', None) - def deleteTempFile(fname = fname, oldexitfunc = oldexitfunc): - fname.unlink() - if oldexitfunc: - oldexitfunc() - - sys.exitfunc = deleteTempFile - - vfs = VirtualFileSystem.getGlobalPtr() - - if not vfs.exists(fname): - raise ArgumentError, "No such file: %s" % (p3dFilename) - - fname.makeAbsolute() - initPackedAppEnvironment() - - mf = Multifile() - if not mf.openRead(fname): - raise ArgumentError, "Not a Panda Multifile: %s" % (p3dFilename) - - # Mount the Multifile under /mf, by convention. - vfs.mount(mf, MultifileRoot, vfs.MFReadOnly) - - # Load any prc files in the root. We have to load them - # explicitly, since the ConfigPageManager can't directly look - # inside the vfs. Use the Multifile interface to find the prc - # files, rather than vfs.scanDirectory(), so we only pick up the - # files in this particular multifile. - for f in mf.getSubfileNames(): - fn = Filename(f) - if fn.getDirname() == '' and fn.getExtension() == 'prc': - pathname = '%s/%s' % (MultifileRoot, f) - data = open(pathname, 'r').read() - loadPrcFileData(pathname, data) - - global gotP3DFilename - gotP3DFilename = True - startIfReady() - -windowPrc = None -def setupWindow(windowType, x, y, width, height, parent): - if windowType == 'hidden': - data = 'window-type none\n' - else: - data = 'window-type onscreen\n' - - if windowType == 'fullscreen': - data += 'fullscreen 1\n' - else: - data += 'fullscreen 0\n' - - if windowType == 'embedded': - data += 'parent-window-handle %s\n' % (parent) - else: - data += 'parent-window-handle 0\n' - - if x or y: - data += 'win-origin %s %s\n' % (x, y) - if width or height: - data += 'win-size %s %s\n' % (width, height) - - global windowPrc - if windowPrc: - unloadPrcFile(windowPrc) - windowPrc = loadPrcFileData("setupWindow", data) - - global gotWindow - gotWindow = True - startIfReady() - -def parseSysArgs(): - """ Converts sys.argv into (p3dFilename, tokens). """ - if len(sys.argv) < 2 or not sys.argv[1]: - raise ArgumentError, "No Panda app specified. Use:\npython RunAppMF.py app.mf" - - tokens = [] - for token in sys.argv[2:]: - if '=' in token: - keyword, value = token.split('=', 1) - else: - keyword = token - value = '' - tokens.append((keyword.lower(), value)) - - p3dFilename = Filename.fromOsSpecific(sys.argv[1]) - osFilename = p3dFilename.toOsSpecific() - if not p3dFilename.exists(): - # If the filename doesn't exist, it must be a URL. - osFilename = '' - if 'src' not in dict(tokens): - tokens.append(('src', sys.argv[1])) - - return (osFilename, tokens) - - - -if __name__ == '__main__': - gotWindow = True - try: - setP3DFilename(*parseSysArgs()) - except ArgumentError, e: - print e.args[0] - sys.exit(1) - run() diff --git a/direct/src/showutil/Sources.pp b/direct/src/showutil/Sources.pp index e69de29bb2..60016ec6b0 100644 --- a/direct/src/showutil/Sources.pp +++ b/direct/src/showutil/Sources.pp @@ -0,0 +1,53 @@ +#define INSTALL_SCRIPTS packp3d.py runp3d.py + +// Generate an appropriate script to invoke the above Python files. +// On Windows, we generate a batch file; on other platforms (including +// Cygwin), we generate a sh script. + +#define install_dir $[$[upcase $[PACKAGE]]_INSTALL] +#define install_bin_dir $[or $[INSTALL_BIN_DIR],$[install_dir]/bin] + +#define python $[PYTHON_COMMAND] +#if $[USE_DEBUG_PYTHON] + #define python $[PYTHON_DEBUG_COMMAND] +#endif + +#foreach scriptname packp3d runp3d + #if $[eq $[PLATFORM],Win32] + #set INSTALL_SCRIPTS $[INSTALL_SCRIPTS] $[scriptname].bat + #else + #set INSTALL_SCRIPTS $[INSTALL_SCRIPTS] $[scriptname] + #endif + + #if $[eq $[PLATFORM],Win32] +#output $[scriptname].bat notouch +@echo off +rem #### Generated automatically by $[PPREMAKE] $[PPREMAKE_VERSION] from $[notdir $[THISFILENAME]]. +rem ################################# DO NOT EDIT ########################### + +$[python] -u $[osfilename $[install_bin_dir]/$[scriptname].py] %1 %2 %3 %4 %5 %6 %7 %8 %9 +#end $[scriptname].bat + +#else // Win32 + +#output $[scriptname] binary notouch +#! /bin/sh +#### Generated automatically by $[PPREMAKE] $[PPREMAKE_VERSION] from $[notdir $[THISFILENAME]]. +################################# DO NOT EDIT ########################### + +#if $[CTPROJS] +# This script was generated while the user was using the ctattach +# tools. That had better still be the case. +#if $[WINDOWS_PLATFORM] +$[python] -u `cygpath -w $DIRECT/built/bin/$[scriptname].py` "$@" +#else +$[python] -u $DIRECT/built/bin/$[scriptname].py "$@" +#endif +#else +$[python] -u '$[osfilename $[install_bin_dir]/$[scriptname].py]' "$@" +#endif +#end $[scriptname] + +#endif // Win32 + +#end scriptname diff --git a/direct/src/showbase/MakeAppMF.py b/direct/src/showutil/packp3d.py old mode 100644 new mode 100755 similarity index 96% rename from direct/src/showbase/MakeAppMF.py rename to direct/src/showutil/packp3d.py index 6239b7c668..aec2c764d9 --- a/direct/src/showbase/MakeAppMF.py +++ b/direct/src/showutil/packp3d.py @@ -1,9 +1,15 @@ -""" -This module will pack a Panda application, consisting of a -directory tree of .py files and models, into a multifile for -distribution and running with RunAppMF.py. To run it, use: +#! /usr/bin/env python -python MakeAppMF.py [opts] app.mf +""" + +This module will pack a Panda application, consisting of a directory +tree of .py files and models, into a p3d file for convenient +distribution. The resulting p3d file can be run by the Panda3D +runtime executable, or by the Panda3D web browser plugin. + +Usage: + + packp3d.py [opts] app.p3d Options: @@ -23,6 +29,10 @@ Options: (this is preferable to having the module start itself immediately upon importing). + Note that your main.py must *not* call run(). This call should + not be part of the p3d file--the Panda3D runtime must be free to + call it, not your code! + -c [py,pyc,pyo] Specifies the compilation mode of python files. 'py' means to @@ -335,7 +345,7 @@ def makePackedApp(args): sys.exit(1) if not args: - raise ArgumentError, "No destination app specified. Use:\npython MakeAppMF.py app.mf" + raise ArgumentError, "No destination app specified. Use:\npackp3d.py app.p3d" multifile_name = args[0] if len(args) > 1: diff --git a/direct/src/showutil/runp3d.py b/direct/src/showutil/runp3d.py new file mode 100755 index 0000000000..a67517b02b --- /dev/null +++ b/direct/src/showutil/runp3d.py @@ -0,0 +1,257 @@ +#! /usr/bin/env python + +""" + +This module is intended to be compiled into the Panda3D runtime +distributable, but it can also be run directly via the Python +interpreter. It will run a Panda3D applet--a p3d file--that has +previously been generated via packp3d.py. + +Usage: + + runp3d.py app.p3d [keyword=value [keyword=value ...] ] + +The command-line keywords mimic the additional parameters that may +appear in HTML syntax when the p3d file appears on a web page. These +are passed as given to the app, which may decide what to do with them. + +See pack3d.py for a script that generates these p3d files. + +""" + +import sys +from direct.showbase import VFSImporter +from direct.showbase.DirectObject import DirectObject +from pandac.PandaModules import VirtualFileSystem, Filename, Multifile, loadPrcFileData, getModelPath, HTTPClient +from direct.stdpy import file +from direct.task.TaskManagerGlobal import taskMgr +import os +import __builtin__ + +MultifileRoot = '/mf' + +# This defines the default prc file that is implicitly loaded with an +# application. +AppPrcFilename = 'App.prc' +AppPrc = """ +default-model-extension .bam +""" + +class ArgumentError(AttributeError): + pass + +class AppRunner(DirectObject): + def __init__(self): + DirectObject.__init__(self) + + self.packedAppEnvironmentInitialized = False + self.gotWindow = False + self.gotP3DFilename = False + self.started = False + self.windowPrc = None + + def initPackedAppEnvironment(self): + """ This function sets up the Python environment suitably for + running a packed app. It should only run once in any given + session (and it includes logic to ensure this). """ + + if self.packedAppEnvironmentInitialized: + return + + self.packedAppEnvironmentInitialized = True + + # We need to make sure sys.stdout maps to sys.stderr instead, so + # if someone makes an unadorned print command within Python code, + # it won't muck up the data stream between parent and child. + sys.stdout = sys.stderr + + vfs = VirtualFileSystem.getGlobalPtr() + + # Clear *all* the mount points, including "/", so that we no + # longer access the disk directly. + vfs.unmountAll() + + # Make sure the directories on our standard Python path are mounted + # read-only, so we can still load Python. + for dirname in sys.path: + vfs.mount(dirname, dirname, vfs.MFReadOnly) + + # Also mount some standard directories read-write (temporary and + # app-data directories). + tdir = Filename.temporary('', '') + for dirname in set([ tdir.getDirname(), + Filename.getTempDirectory().cStr(), + Filename.getUserAppdataDirectory().cStr(), + Filename.getCommonAppdataDirectory().cStr() ]): + vfs.mount(dirname, dirname, 0) + + # Now set up Python to import this stuff. + VFSImporter.register() + sys.path = [ MultifileRoot ] + sys.path + + # Put our root directory on the model-path and prc-path, too. + getModelPath().prependDirectory(MultifileRoot) + + # Load the implicit App.prc file. + loadPrcFileData(AppPrcFilename, AppPrc) + + # Replace the builtin open and file symbols so user code will get + # our versions by default, which can open and read files out of + # the multifile. + __builtin__.file = file.file + __builtin__.open = file.open + os.listdir = file.listdir + os.walk = file.walk + + # Make "/mf" our "current directory", for running the multifiles + # we plan to mount there. + vfs.chdir(MultifileRoot) + + def startIfReady(self): + if self.started: + return + + if self.gotWindow and self.gotP3DFilename: + self.started = True + + # Hang a hook so we know when the window is actually opened. + self.acceptOnce('window-event', self.windowEvent) + + import main + if hasattr(main, 'main') and callable(main.main): + main.main() + + def setP3DFilename(self, p3dFilename, tokens = []): + tokenDict = dict(tokens) + fname = Filename.fromOsSpecific(p3dFilename) + if not p3dFilename: + # If we didn't get a literal filename, we have to download it + # from the URL. TODO: make this a smarter temporary filename? + fname = Filename.temporary('', 'p3d_') + fname.setExtension('p3d') + p3dFilename = fname.toOsSpecific() + src = tokenDict.get('src', None) + if not src: + raise ArgumentError, "No Panda app specified." + + http = HTTPClient.getGlobalPtr() + hc = http.getDocument(src) + if not hc.downloadToFile(fname): + fname.unlink() + raise ArgumentError, "Couldn't download %s" % (src) + + # Set a hook on sys.exit to delete the temporary file. + oldexitfunc = getattr(sys, 'exitfunc', None) + def deleteTempFile(fname = fname, oldexitfunc = oldexitfunc): + fname.unlink() + if oldexitfunc: + oldexitfunc() + + sys.exitfunc = deleteTempFile + + vfs = VirtualFileSystem.getGlobalPtr() + + if not vfs.exists(fname): + raise ArgumentError, "No such file: %s" % (p3dFilename) + + fname.makeAbsolute() + self.initPackedAppEnvironment() + + mf = Multifile() + if not mf.openRead(fname): + raise ArgumentError, "Not a Panda Multifile: %s" % (p3dFilename) + + # Mount the Multifile under /mf, by convention. + vfs.mount(mf, MultifileRoot, vfs.MFReadOnly) + + # Load any prc files in the root. We have to load them + # explicitly, since the ConfigPageManager can't directly look + # inside the vfs. Use the Multifile interface to find the prc + # files, rather than vfs.scanDirectory(), so we only pick up the + # files in this particular multifile. + for f in mf.getSubfileNames(): + fn = Filename(f) + if fn.getDirname() == '' and fn.getExtension() == 'prc': + pathname = '%s/%s' % (MultifileRoot, f) + data = open(pathname, 'r').read() + loadPrcFileData(pathname, data) + + self.gotP3DFilename = True + self.startIfReady() + + def setupWindow(self, windowType, x, y, width, height, parent): + if windowType == 'hidden': + data = 'window-type none\n' + else: + data = 'window-type onscreen\n' + + if windowType == 'fullscreen': + data += 'fullscreen 1\n' + else: + data += 'fullscreen 0\n' + + if windowType == 'embedded': + data += 'parent-window-handle %s\n' % (parent) + else: + data += 'parent-window-handle 0\n' + + if x or y: + data += 'win-origin %s %s\n' % (x, y) + if width or height: + data += 'win-size %s %s\n' % (width, height) + + if self.windowPrc: + unloadPrcFile(self.windowPrc) + self.windowPrc = loadPrcFileData("setupWindow", data) + + self.gotWindow = True + self.startIfReady() + + def windowEvent(self, win): + print "Got window event in runp3d" + + # TODO: feed this information back to the plugin host. + + def parseSysArgs(self): + """ Converts sys.argv into (p3dFilename, tokens). """ + import getopt + opts, args = getopt.getopt(sys.argv[1:], 'h') + + for option, value in opts: + if option == '-h': + print __doc__ + sys.exit(1) + + if not args or not args[0]: + raise ArgumentError, "No Panda app specified. Use:\nrunp3d.py app.p3d" + + tokens = [] + for token in args[1:]: + if '=' in token: + keyword, value = token.split('=', 1) + else: + keyword = token + value = '' + tokens.append((keyword.lower(), value)) + + p3dFilename = Filename.fromOsSpecific(sys.argv[1]) + osFilename = p3dFilename.toOsSpecific() + if not p3dFilename.exists(): + # If the filename doesn't exist, it must be a URL. + osFilename = '' + if 'src' not in dict(tokens): + tokens.append(('src', sys.argv[1])) + + return (osFilename, tokens) + + + +if __name__ == '__main__': + runner = AppRunner() + runner.gotWindow = True + try: + runner.setP3DFilename(*runner.parseSysArgs()) + except ArgumentError, e: + print e.args[0] + sys.exit(1) + run()