|
|
@@ -39,6 +39,7 @@
|
|
|
#include "load_plugin.h"
|
|
|
#include "find_root_dir.h"
|
|
|
#include "mkdir_complete.h"
|
|
|
+#include "parse_color.h"
|
|
|
|
|
|
// We can include this header file to get the DTOOL_PLATFORM
|
|
|
// definition, even though we don't link with dtool.
|
|
|
@@ -86,15 +87,70 @@ PPInstance::PPInstance( CP3DActiveXCtrl& parentCtrl ) :
|
|
|
_contents_expiration = 0;
|
|
|
_failed = false;
|
|
|
|
|
|
+ _tokens = NULL;
|
|
|
+ _num_tokens = 0;
|
|
|
+
|
|
|
// Ensure this event is initially in the "set" state, in case we
|
|
|
// never get a download request before we get a close request.
|
|
|
m_eventDownloadStopped.SetEvent( );
|
|
|
+ m_eventStop.ResetEvent();
|
|
|
|
|
|
nout << "Plugin is built with " << PANDA_PACKAGE_HOST_URL << "\n";
|
|
|
}
|
|
|
|
|
|
-PPInstance::~PPInstance( )
|
|
|
-{
|
|
|
+PPInstance::~PPInstance() {
|
|
|
+ assert(_tokens == NULL);
|
|
|
+}
|
|
|
+
|
|
|
+// This is called at setup time to read the set of web tokens from the
|
|
|
+// ActiveX control.
|
|
|
+void PPInstance::
|
|
|
+read_tokens() {
|
|
|
+ assert(_tokens == NULL);
|
|
|
+ _num_tokens = (int)m_parentCtrl.m_parameters.size();
|
|
|
+ _tokens = new P3D_token[ _num_tokens ];
|
|
|
+ for (int i = 0; i < _num_tokens; i++ ) {
|
|
|
+ std::pair< CString, CString > keyAndValue = m_parentCtrl.m_parameters[ i ];
|
|
|
+ // Make the token lowercase, since HTML is case-insensitive but
|
|
|
+ // we're not.
|
|
|
+ string keyword;
|
|
|
+ for (const char *p = m_parentCtrl.m_parameters[ i ].first; *p; ++p) {
|
|
|
+ keyword += tolower(*p);
|
|
|
+ }
|
|
|
+
|
|
|
+ _tokens[i]._keyword = strdup( keyword.c_str() );
|
|
|
+ _tokens[i]._value = strdup( m_parentCtrl.m_parameters[ i ].second );
|
|
|
+ }
|
|
|
+
|
|
|
+ // fgcolor and bgcolor are useful to know here (in case we have to
|
|
|
+ // draw a twirling icon).
|
|
|
+
|
|
|
+ // The default bgcolor is white.
|
|
|
+ _bgcolor_r = _bgcolor_g = _bgcolor_b = 0xff;
|
|
|
+ if (has_token("bgcolor")) {
|
|
|
+ int r, g, b;
|
|
|
+ if (parse_color(r, g, b, lookup_token("bgcolor"))) {
|
|
|
+ _bgcolor_r = r;
|
|
|
+ _bgcolor_g = g;
|
|
|
+ _bgcolor_b = b;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // The default fgcolor is either black or white, according to the
|
|
|
+ // brightness of the bgcolor.
|
|
|
+ if (_bgcolor_r + _bgcolor_g + _bgcolor_b > 0x80 + 0x80 + 0x80) {
|
|
|
+ _fgcolor_r = _fgcolor_g = _fgcolor_b = 0x00;
|
|
|
+ } else {
|
|
|
+ _fgcolor_r = _fgcolor_g = _fgcolor_b = 0xff;
|
|
|
+ }
|
|
|
+ if (has_token("fgcolor")) {
|
|
|
+ int r, g, b;
|
|
|
+ if (parse_color(r, g, b, lookup_token("fgcolor"))) {
|
|
|
+ _fgcolor_r = r;
|
|
|
+ _fgcolor_g = g;
|
|
|
+ _fgcolor_b = b;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
int PPInstance::DownloadFile( const std::string& from, const std::string& to )
|
|
|
@@ -499,6 +555,8 @@ int PPInstance::DownloadP3DComponents( std::string& p3dDllFilename )
|
|
|
|
|
|
int PPInstance::LoadPlugin( const std::string& dllFilename )
|
|
|
{
|
|
|
+ CSingleLock lock(&_load_mutex);
|
|
|
+ lock.Lock();
|
|
|
if ( !m_pluginLoaded )
|
|
|
{
|
|
|
ref_plugin();
|
|
|
@@ -558,6 +616,9 @@ int PPInstance::LoadPlugin( const std::string& dllFilename )
|
|
|
|
|
|
int PPInstance::UnloadPlugin()
|
|
|
{
|
|
|
+ CSingleLock lock(&_load_mutex);
|
|
|
+ lock.Lock();
|
|
|
+
|
|
|
int error( 0 );
|
|
|
|
|
|
if ( m_pluginLoaded )
|
|
|
@@ -586,7 +647,7 @@ unref_plugin() {
|
|
|
|
|
|
if ( s_instanceCount == 0 && is_plugin_loaded() ) {
|
|
|
nout << "Unloading core API\n";
|
|
|
- unload_plugin();
|
|
|
+ unload_plugin(nout);
|
|
|
|
|
|
// This pointer is no longer valid and must be reset for next
|
|
|
// time.
|
|
|
@@ -596,7 +657,13 @@ unref_plugin() {
|
|
|
|
|
|
int PPInstance::Start( const std::string& p3dFilename )
|
|
|
{
|
|
|
- m_eventStop.ResetEvent();
|
|
|
+ {
|
|
|
+ CSingleLock lock(&_load_mutex);
|
|
|
+ lock.Lock();
|
|
|
+
|
|
|
+ assert(!m_isInit);
|
|
|
+ m_isInit = true;
|
|
|
+ }
|
|
|
|
|
|
P3D_window_handle parent_window;
|
|
|
memset(&parent_window, 0, sizeof(parent_window));
|
|
|
@@ -606,29 +673,8 @@ int PPInstance::Start( const std::string& p3dFilename )
|
|
|
RECT rect;
|
|
|
GetClientRect( m_parentCtrl.m_hWnd, &rect );
|
|
|
|
|
|
- P3D_token* p3dTokens = new P3D_token[ m_parentCtrl.m_parameters.size() ];
|
|
|
- for ( UINT i = 0; i < m_parentCtrl.m_parameters.size(); i++ )
|
|
|
- {
|
|
|
- std::pair< CString, CString > keyAndValue = m_parentCtrl.m_parameters[ i ];
|
|
|
- // Make the token lowercase, since HTML is case-insensitive but
|
|
|
- // we're not.
|
|
|
- string keyword;
|
|
|
- for (const char *p = m_parentCtrl.m_parameters[ i ].first; *p; ++p) {
|
|
|
- keyword += tolower(*p);
|
|
|
- }
|
|
|
-
|
|
|
- p3dTokens[i]._keyword = strdup( keyword.c_str() );
|
|
|
- p3dTokens[i]._value = strdup( m_parentCtrl.m_parameters[ i ].second );
|
|
|
- }
|
|
|
- nout << "Creating new P3D instance object \n";
|
|
|
- m_p3dInstance = P3D_new_instance_ptr( &P3D_NotificationSync, p3dTokens, m_parentCtrl.m_parameters.size(), 0, NULL, (void*)&m_parentCtrl );
|
|
|
-
|
|
|
- for ( UINT j = 0; j < m_parentCtrl.m_parameters.size(); j++ )
|
|
|
- {
|
|
|
- delete [] p3dTokens[j]._keyword;
|
|
|
- delete [] p3dTokens[j]._value;
|
|
|
- }
|
|
|
- delete [] p3dTokens;
|
|
|
+ nout << "Creating new P3D instance object for " << p3dFilename << "\n";
|
|
|
+ m_p3dInstance = P3D_new_instance_ptr( &P3D_NotificationSync, _tokens, _num_tokens, 0, NULL, (void*)&m_parentCtrl );
|
|
|
|
|
|
if ( !m_p3dInstance )
|
|
|
{
|
|
|
@@ -646,15 +692,12 @@ int PPInstance::Start( const std::string& p3dFilename )
|
|
|
P3D_instance_setup_window_ptr( m_p3dInstance, P3D_WT_embedded, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, &parent_window );
|
|
|
|
|
|
nout << "Starting new P3D instance " << p3dFilename << "\n";
|
|
|
-
|
|
|
if ( !P3D_instance_start_ptr( m_p3dInstance, false, p3dFilename.c_str(), 0 ) )
|
|
|
{
|
|
|
nout << "Error starting P3D instance: " << GetLastError() << "\n";
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
- m_isInit = true;
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
@@ -676,6 +719,17 @@ int PPInstance::Stop( )
|
|
|
{
|
|
|
UnloadPlugin();
|
|
|
}
|
|
|
+
|
|
|
+ if (_tokens != NULL) {
|
|
|
+ for ( int j = 0; j < _num_tokens; ++j) {
|
|
|
+ delete [] _tokens[j]._keyword;
|
|
|
+ delete [] _tokens[j]._value;
|
|
|
+ }
|
|
|
+ delete [] _tokens;
|
|
|
+ _tokens = NULL;
|
|
|
+ _num_tokens = 0;
|
|
|
+ }
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
@@ -839,33 +893,6 @@ HandleRequest( P3D_request *request ) {
|
|
|
return continue_loop;
|
|
|
}
|
|
|
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-// Function: PPInstance::lookup_token
|
|
|
-// Access: Private
|
|
|
-// Description: Returns the value associated with the first
|
|
|
-// appearance of the named token, or empty string if the
|
|
|
-// token does not appear.
|
|
|
-////////////////////////////////////////////////////////////////////
|
|
|
-string PPInstance::
|
|
|
-lookup_token(const string &keyword) const {
|
|
|
- for (UINT i = 0; i < m_parentCtrl.m_parameters.size(); i++) {
|
|
|
- std::pair<CString, CString> keyAndValue = m_parentCtrl.m_parameters[i];
|
|
|
- // Make the token lowercase, since HTML is case-insensitive but
|
|
|
- // we're not.
|
|
|
- const CString &orig_keyword = m_parentCtrl.m_parameters[i].first;
|
|
|
- string lower_keyword;
|
|
|
- for (const char *p = orig_keyword; *p; ++p) {
|
|
|
- lower_keyword += tolower(*p);
|
|
|
- }
|
|
|
-
|
|
|
- if (lower_keyword == keyword) {
|
|
|
- return (const char *)m_parentCtrl.m_parameters[i].second;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return string();
|
|
|
-}
|
|
|
-
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// Function: PPInstance::compare_seq
|
|
|
// Access: Private, Static
|
|
|
@@ -963,4 +990,38 @@ set_failed() {
|
|
|
}
|
|
|
|
|
|
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: PPInstance::lookup_token
|
|
|
+// Access: Private
|
|
|
+// Description: Returns the value associated with the first
|
|
|
+// appearance of the named token, or empty string if the
|
|
|
+// token does not appear.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+std::string PPInstance::
|
|
|
+lookup_token(const std::string &keyword) const {
|
|
|
+ for (int i = 0; i < _num_tokens; ++i) {
|
|
|
+ if (strcmp(_tokens[i]._keyword, keyword.c_str()) == 0) {
|
|
|
+ return _tokens[i]._value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return string();
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+// Function: PPInstance::has_token
|
|
|
+// Access: Private
|
|
|
+// Description: Returns true if the named token appears in the list,
|
|
|
+// false otherwise.
|
|
|
+////////////////////////////////////////////////////////////////////
|
|
|
+bool PPInstance::
|
|
|
+has_token(const std::string &keyword) const {
|
|
|
+ for (int i = 0; i < _num_tokens; ++i) {
|
|
|
+ if (strcmp(_tokens[i]._keyword, keyword.c_str()) == 0) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
|