mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
it continues
This commit is contained in:
parent
a6c1759080
commit
8a48e4593e
@ -29,12 +29,15 @@ int P3DInstance::_next_instance_id = 0;
|
|||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
P3DInstance::
|
P3DInstance::
|
||||||
P3DInstance(P3D_request_ready_func *func,
|
P3DInstance(P3D_request_ready_func *func, void *user_data,
|
||||||
const string &p3d_filename,
|
const string &p3d_filename,
|
||||||
const P3D_token tokens[], size_t num_tokens) :
|
const P3D_token tokens[], size_t num_tokens) :
|
||||||
_func(func),
|
_func(func),
|
||||||
_fparams(p3d_filename, tokens, num_tokens)
|
_fparams(p3d_filename, tokens, num_tokens)
|
||||||
{
|
{
|
||||||
|
_user_data = user_data;
|
||||||
|
_request_pending = false;
|
||||||
|
|
||||||
_instance_id = _next_instance_id;
|
_instance_id = _next_instance_id;
|
||||||
++_next_instance_id;
|
++_next_instance_id;
|
||||||
|
|
||||||
@ -169,9 +172,13 @@ P3D_request *P3DInstance::
|
|||||||
get_request() {
|
get_request() {
|
||||||
P3D_request *result = NULL;
|
P3D_request *result = NULL;
|
||||||
ACQUIRE_LOCK(_request_lock);
|
ACQUIRE_LOCK(_request_lock);
|
||||||
|
nout << "P3DInstance::get_request() called on " << this
|
||||||
|
<< ", " << _pending_requests.size() << " requests in queue\n";
|
||||||
if (!_pending_requests.empty()) {
|
if (!_pending_requests.empty()) {
|
||||||
result = _pending_requests.front();
|
result = _pending_requests.front();
|
||||||
|
nout << "popped request " << result << "\n";
|
||||||
_pending_requests.pop_front();
|
_pending_requests.pop_front();
|
||||||
|
_request_pending = !_pending_requests.empty();
|
||||||
}
|
}
|
||||||
RELEASE_LOCK(_request_lock);
|
RELEASE_LOCK(_request_lock);
|
||||||
|
|
||||||
@ -186,13 +193,21 @@ get_request() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DInstance::
|
void P3DInstance::
|
||||||
add_request(P3D_request *request) {
|
add_request(P3D_request *request) {
|
||||||
nout << "adding a request\n";
|
nout << "adding request " << request << " in " << this << "\n";
|
||||||
assert(request->_instance == this);
|
assert(request->_instance == this);
|
||||||
|
|
||||||
ACQUIRE_LOCK(_request_lock);
|
ACQUIRE_LOCK(_request_lock);
|
||||||
_pending_requests.push_back(request);
|
_pending_requests.push_back(request);
|
||||||
|
_request_pending = true;
|
||||||
RELEASE_LOCK(_request_lock);
|
RELEASE_LOCK(_request_lock);
|
||||||
|
|
||||||
|
// Asynchronous notification for anyone who cares.
|
||||||
|
nout << "request_ready, calling " << _func << "\n" << flush;
|
||||||
|
if (_func != NULL) {
|
||||||
|
_func(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Synchronous notification for pollers.
|
||||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
inst_mgr->signal_request_ready();
|
inst_mgr->signal_request_ready();
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ class P3DPackage;
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class P3DInstance : public P3D_instance {
|
class P3DInstance : public P3D_instance {
|
||||||
public:
|
public:
|
||||||
P3DInstance(P3D_request_ready_func *func,
|
P3DInstance(P3D_request_ready_func *func, void *user_data,
|
||||||
const string &p3d_filename,
|
const string &p3d_filename,
|
||||||
const P3D_token tokens[], size_t num_tokens);
|
const P3D_token tokens[], size_t num_tokens);
|
||||||
~P3DInstance();
|
~P3DInstance();
|
||||||
|
@ -112,9 +112,10 @@ initialize() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
P3DInstance *P3DInstanceManager::
|
P3DInstance *P3DInstanceManager::
|
||||||
create_instance(P3D_request_ready_func *func,
|
create_instance(P3D_request_ready_func *func,
|
||||||
|
void *user_data,
|
||||||
const string &p3d_filename,
|
const string &p3d_filename,
|
||||||
const P3D_token tokens[], size_t num_tokens) {
|
const P3D_token tokens[], size_t num_tokens) {
|
||||||
P3DInstance *inst = new P3DInstance(func, p3d_filename,
|
P3DInstance *inst = new P3DInstance(func, user_data, p3d_filename,
|
||||||
tokens, num_tokens);
|
tokens, num_tokens);
|
||||||
_instances.insert(inst);
|
_instances.insert(inst);
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ public:
|
|||||||
|
|
||||||
P3DInstance *
|
P3DInstance *
|
||||||
create_instance(P3D_request_ready_func *func,
|
create_instance(P3D_request_ready_func *func,
|
||||||
|
void *user_data,
|
||||||
const string &p3d_filename,
|
const string &p3d_filename,
|
||||||
const P3D_token tokens[], size_t num_tokens);
|
const P3D_token tokens[], size_t num_tokens);
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ P3D_free_string(char *string) {
|
|||||||
|
|
||||||
P3D_instance *
|
P3D_instance *
|
||||||
P3D_create_instance(P3D_request_ready_func *func,
|
P3D_create_instance(P3D_request_ready_func *func,
|
||||||
|
void *user_data,
|
||||||
const char *p3d_filename,
|
const char *p3d_filename,
|
||||||
const P3D_token tokens[], size_t num_tokens) {
|
const P3D_token tokens[], size_t num_tokens) {
|
||||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||||
@ -80,7 +81,7 @@ P3D_create_instance(P3D_request_ready_func *func,
|
|||||||
}
|
}
|
||||||
|
|
||||||
P3DInstance *result =
|
P3DInstance *result =
|
||||||
inst_mgr->create_instance(func, p3d_filename, tokens, num_tokens);
|
inst_mgr->create_instance(func, user_data, p3d_filename, tokens, num_tokens);
|
||||||
RELEASE_LOCK(_lock);
|
RELEASE_LOCK(_lock);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -148,7 +149,9 @@ P3D_request *
|
|||||||
P3D_instance_get_request(P3D_instance *instance) {
|
P3D_instance_get_request(P3D_instance *instance) {
|
||||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||||
ACQUIRE_LOCK(_lock);
|
ACQUIRE_LOCK(_lock);
|
||||||
|
nout << "P3D_instance_get_request(" << instance << ")\n";
|
||||||
P3D_request *result = ((P3DInstance *)instance)->get_request();
|
P3D_request *result = ((P3DInstance *)instance)->get_request();
|
||||||
|
nout << " result = " << result << "\n" << flush;
|
||||||
RELEASE_LOCK(_lock);
|
RELEASE_LOCK(_lock);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -160,6 +163,8 @@ P3D_check_request(bool wait) {
|
|||||||
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
|
||||||
P3D_instance *inst = inst_mgr->check_request();
|
P3D_instance *inst = inst_mgr->check_request();
|
||||||
|
|
||||||
|
nout << "P3D_instance_check_request, inst = " << inst << "\n";
|
||||||
|
|
||||||
if (inst != NULL || !wait) {
|
if (inst != NULL || !wait) {
|
||||||
RELEASE_LOCK(_lock);
|
RELEASE_LOCK(_lock);
|
||||||
return inst;
|
return inst;
|
||||||
@ -192,13 +197,14 @@ P3D_instance_feed_url_stream(P3D_instance *instance, int unique_id,
|
|||||||
P3D_result_code result_code,
|
P3D_result_code result_code,
|
||||||
int http_status_code,
|
int http_status_code,
|
||||||
size_t total_expected_data,
|
size_t total_expected_data,
|
||||||
const unsigned char *this_data,
|
const void *this_data,
|
||||||
size_t this_data_size) {
|
size_t this_data_size) {
|
||||||
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
assert(P3DInstanceManager::get_global_ptr()->is_initialized());
|
||||||
ACQUIRE_LOCK(_lock);
|
ACQUIRE_LOCK(_lock);
|
||||||
bool result = ((P3DInstance *)instance)->
|
bool result = ((P3DInstance *)instance)->
|
||||||
feed_url_stream(unique_id, result_code, http_status_code,
|
feed_url_stream(unique_id, result_code, http_status_code,
|
||||||
total_expected_data, this_data, this_data_size);
|
total_expected_data,
|
||||||
|
(const unsigned char *)this_data, this_data_size);
|
||||||
RELEASE_LOCK(_lock);
|
RELEASE_LOCK(_lock);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -111,11 +111,16 @@ P3D_free_string_func(char *string);
|
|||||||
instances operate generally independently of each other. */
|
instances operate generally independently of each other. */
|
||||||
|
|
||||||
/* This structure defines the handle to a single instance. The host
|
/* This structure defines the handle to a single instance. The host
|
||||||
may access the _request_pending member, which will be true if the
|
may access any members appearing here. */
|
||||||
host should call P3D_instance_get_request(). */
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
/* true if the host should call P3D_instance_get_request().*/
|
||||||
bool _request_pending;
|
bool _request_pending;
|
||||||
|
|
||||||
|
/* an opaque pointer the host may use to store private data that the
|
||||||
|
plugin does not interpret. This pointer can be directly set, or
|
||||||
|
it can be initialized in the P3D_create_instance() call. */
|
||||||
|
void *_user_data;
|
||||||
|
|
||||||
/* Additional opaque data may be stored here. */
|
/* Additional opaque data may be stored here. */
|
||||||
} P3D_instance;
|
} P3D_instance;
|
||||||
|
|
||||||
@ -199,6 +204,12 @@ typedef struct {
|
|||||||
instance. If this is empty or NULL, the "src" token (below) will
|
instance. If this is empty or NULL, the "src" token (below) will
|
||||||
be downloaded instead.
|
be downloaded instead.
|
||||||
|
|
||||||
|
The user_data pointer is any arbitrary pointer value; it will be
|
||||||
|
copied into the _user_data member of the new P3D_instance object.
|
||||||
|
This pointer is intended for the host to use to store private data
|
||||||
|
associated with each instance; the plugin will not do anything with
|
||||||
|
this data.
|
||||||
|
|
||||||
For tokens, pass an array of P3D_token elements (above), which
|
For tokens, pass an array of P3D_token elements (above), which
|
||||||
correspond to the user-supplied keyword/value pairs that may appear
|
correspond to the user-supplied keyword/value pairs that may appear
|
||||||
in the embed token within the HTML syntax; the host is responsible
|
in the embed token within the HTML syntax; the host is responsible
|
||||||
@ -222,6 +233,7 @@ typedef struct {
|
|||||||
|
|
||||||
typedef P3D_instance *
|
typedef P3D_instance *
|
||||||
P3D_create_instance_func(P3D_request_ready_func *func,
|
P3D_create_instance_func(P3D_request_ready_func *func,
|
||||||
|
void *user_data,
|
||||||
const char *p3d_filename,
|
const char *p3d_filename,
|
||||||
const P3D_token tokens[], size_t num_tokens);
|
const P3D_token tokens[], size_t num_tokens);
|
||||||
|
|
||||||
@ -446,7 +458,7 @@ P3D_instance_feed_url_stream_func(P3D_instance *instance, int unique_id,
|
|||||||
P3D_result_code result_code,
|
P3D_result_code result_code,
|
||||||
int http_status_code,
|
int http_status_code,
|
||||||
size_t total_expected_data,
|
size_t total_expected_data,
|
||||||
const unsigned char *this_data,
|
const void *this_data,
|
||||||
size_t this_data_size);
|
size_t this_data_size);
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#if $[WINDOWS_PLATFORM]
|
#if $[WINDOWS_PLATFORM]
|
||||||
#define WIN_RESOURCE_FILE nppanda3d.rc
|
#define WIN_RESOURCE_FILE nppanda3d.rc
|
||||||
#define LINKER_DEF_FILE nppanda3d.def
|
#define LINKER_DEF_FILE nppanda3d.def
|
||||||
|
#define WIN_SYS_LIBS user32.lib
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Mac-specific options.
|
// Mac-specific options.
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
inline PPDownloadRequest::
|
inline PPDownloadRequest::
|
||||||
PPDownloadRequest(RequestType rtype, int user_id) :
|
PPDownloadRequest(RequestType rtype, int user_id) :
|
||||||
_rtype(rtype),
|
_rtype(rtype),
|
||||||
_user_id(user_id)
|
_user_id(user_id),
|
||||||
|
_notified_done(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,3 +13,4 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "ppDownloadRequest.h"
|
#include "ppDownloadRequest.h"
|
||||||
|
|
||||||
|
@ -36,6 +36,10 @@ public:
|
|||||||
public:
|
public:
|
||||||
RequestType _rtype;
|
RequestType _rtype;
|
||||||
int _user_id;
|
int _user_id;
|
||||||
|
|
||||||
|
// This is sent true when we have notified the plugin that the
|
||||||
|
// stream is done.
|
||||||
|
bool _notified_done;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "ppDownloadRequest.I"
|
#include "ppDownloadRequest.I"
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "ppInstance.h"
|
#include "ppInstance.h"
|
||||||
|
#include "startup.h"
|
||||||
#include "p3d_plugin_config.h"
|
#include "p3d_plugin_config.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -27,7 +28,7 @@ PPInstance::
|
|||||||
PPInstance(NPMIMEType pluginType, NPP instance, uint16 mode,
|
PPInstance(NPMIMEType pluginType, NPP instance, uint16 mode,
|
||||||
int16 argc, char *argn[], char *argv[], NPSavedData *saved) {
|
int16 argc, char *argn[], char *argv[], NPSavedData *saved) {
|
||||||
logfile << "constructing " << this << "\n" << flush;
|
logfile << "constructing " << this << "\n" << flush;
|
||||||
_inst = NULL;
|
_p3d_inst = NULL;
|
||||||
|
|
||||||
_npp_instance = instance;
|
_npp_instance = instance;
|
||||||
_npp_mode = mode;
|
_npp_mode = mode;
|
||||||
@ -69,9 +70,9 @@ PPInstance::
|
|||||||
logfile
|
logfile
|
||||||
<< "destructing " << this << "\n" << flush;
|
<< "destructing " << this << "\n" << flush;
|
||||||
|
|
||||||
if (_inst != NULL) {
|
if (_p3d_inst != NULL) {
|
||||||
P3D_instance_finish(_inst);
|
P3D_instance_finish(_p3d_inst);
|
||||||
_inst = NULL;
|
_p3d_inst = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the tokens we allocated.
|
// Free the tokens we allocated.
|
||||||
@ -101,7 +102,7 @@ set_window(NPWindow *window) {
|
|||||||
_window = *window;
|
_window = *window;
|
||||||
_got_window = true;
|
_got_window = true;
|
||||||
|
|
||||||
if (_inst == NULL) {
|
if (_p3d_inst == NULL) {
|
||||||
create_instance();
|
create_instance();
|
||||||
} else {
|
} else {
|
||||||
send_window();
|
send_window();
|
||||||
@ -139,6 +140,12 @@ new_stream(NPMIMEType type, NPStream *stream, bool seekable, uint16 *stype) {
|
|||||||
*stype = NP_ASFILEONLY;
|
*stype = NP_ASFILEONLY;
|
||||||
return NPERR_NO_ERROR;
|
return NPERR_NO_ERROR;
|
||||||
|
|
||||||
|
case PPDownloadRequest::RT_user:
|
||||||
|
// This is a request from the plugin. We'll receive this as a
|
||||||
|
// stream.
|
||||||
|
*stype = NP_NORMAL;
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Don't know what this is.
|
// Don't know what this is.
|
||||||
logfile << "Unexpected request " << (int)req->_rtype << "\n";
|
logfile << "Unexpected request " << (int)req->_rtype << "\n";
|
||||||
@ -147,6 +154,35 @@ new_stream(NPMIMEType type, NPStream *stream, bool seekable, uint16 *stype) {
|
|||||||
return NPERR_GENERIC_ERROR;
|
return NPERR_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PPInstance::write_stream
|
||||||
|
// Access: Public
|
||||||
|
// Description: Called by the browser to feed data read from a URL or
|
||||||
|
// whatever.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int PPInstance::
|
||||||
|
write_stream(NPStream *stream, int offset, int len, void *buffer) {
|
||||||
|
if (stream->notifyData == NULL) {
|
||||||
|
logfile << "Unexpected write_stream on " << stream->url << "\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPDownloadRequest *req = (PPDownloadRequest *)(stream->notifyData);
|
||||||
|
switch (req->_rtype) {
|
||||||
|
case PPDownloadRequest::RT_user:
|
||||||
|
P3D_instance_feed_url_stream(_p3d_inst, req->_user_id,
|
||||||
|
P3D_RC_in_progress, 0,
|
||||||
|
stream->end, buffer, len);
|
||||||
|
return len;
|
||||||
|
|
||||||
|
default:
|
||||||
|
logfile << "Unexpected write_stream on " << stream->url << "\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PPInstance::destroy_stream
|
// Function: PPInstance::destroy_stream
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -156,6 +192,37 @@ new_stream(NPMIMEType type, NPStream *stream, bool seekable, uint16 *stype) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
NPError PPInstance::
|
NPError PPInstance::
|
||||||
destroy_stream(NPStream *stream, NPReason reason) {
|
destroy_stream(NPStream *stream, NPReason reason) {
|
||||||
|
if (stream->notifyData == NULL) {
|
||||||
|
logfile << "Unexpected destroy_stream on " << stream->url << "\n";
|
||||||
|
return NPERR_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPDownloadRequest *req = (PPDownloadRequest *)(stream->notifyData);
|
||||||
|
switch (req->_rtype) {
|
||||||
|
case PPDownloadRequest::RT_user:
|
||||||
|
{
|
||||||
|
P3D_result_code result_code = P3D_RC_done;
|
||||||
|
if (reason != NPRES_DONE) {
|
||||||
|
result_code = P3D_RC_generic_error;
|
||||||
|
}
|
||||||
|
assert(!req->_notified_done);
|
||||||
|
P3D_instance_feed_url_stream(_p3d_inst, req->_user_id,
|
||||||
|
result_code, 0, stream->end, NULL, 0);
|
||||||
|
req->_notified_done = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPDownloadRequest::RT_core_dll:
|
||||||
|
// This is the one case we don't start with GetUrlNotify, so we'll
|
||||||
|
// never get a url_notify call on this one. So, we have to delete
|
||||||
|
// the PPDownloadRequest object here.
|
||||||
|
delete req;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return NPERR_NO_ERROR;
|
return NPERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +236,36 @@ destroy_stream(NPStream *stream, NPReason reason) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PPInstance::
|
void PPInstance::
|
||||||
url_notify(const char *url, NPReason reason, void *notifyData) {
|
url_notify(const char *url, NPReason reason, void *notifyData) {
|
||||||
|
if (notifyData == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PPDownloadRequest *req = (PPDownloadRequest *)notifyData;
|
||||||
|
switch (req->_rtype) {
|
||||||
|
case PPDownloadRequest::RT_user:
|
||||||
|
if (!req->_notified_done) {
|
||||||
|
// We shouldn't have gotten here without notifying the stream
|
||||||
|
// unless the stream never got started (and hence we never
|
||||||
|
// called destroy_stream().
|
||||||
|
logfile << "Failure starting stream\n" << flush;
|
||||||
|
assert(reason != NPRES_DONE);
|
||||||
|
|
||||||
|
P3D_instance_feed_url_stream(_p3d_inst, req->_user_id,
|
||||||
|
P3D_RC_generic_error, 0, 0, NULL, 0);
|
||||||
|
req->_notified_done = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PPDownloadRequest::RT_core_dll:
|
||||||
|
// Shouldn't be possible to get here.
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete req;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -189,6 +286,8 @@ stream_as_file(NPStream *stream, const char *fname) {
|
|||||||
// Safari seems to want to report the filename in the old-style form
|
// Safari seems to want to report the filename in the old-style form
|
||||||
// "Macintosh HD:blah:blah:blah" instead of the new-style form
|
// "Macintosh HD:blah:blah:blah" instead of the new-style form
|
||||||
// "/blah/blah/blah". How annoying.
|
// "/blah/blah/blah". How annoying.
|
||||||
|
|
||||||
|
// TODO: Is "Macintosh HD:" the only possible prefix?
|
||||||
if (filename.substr(0, 13) == "Macintosh HD:") {
|
if (filename.substr(0, 13) == "Macintosh HD:") {
|
||||||
string fname2;
|
string fname2;
|
||||||
for (size_t p = 12; p < filename.size(); ++p) {
|
for (size_t p = 12; p < filename.size(); ++p) {
|
||||||
@ -212,6 +311,7 @@ stream_as_file(NPStream *stream, const char *fname) {
|
|||||||
logfile << "got plugin\n";
|
logfile << "got plugin\n";
|
||||||
if (!load_plugin(filename)) {
|
if (!load_plugin(filename)) {
|
||||||
logfile << "Unable to launch core API.\n";
|
logfile << "Unable to launch core API.\n";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
create_instance();
|
create_instance();
|
||||||
break;
|
break;
|
||||||
@ -230,6 +330,54 @@ stream_as_file(NPStream *stream, const char *fname) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PPInstance::handle_request
|
||||||
|
// Access: Public
|
||||||
|
// Description: Handles a request from the plugin, forwarding
|
||||||
|
// it to the browser as appropriate.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PPInstance::
|
||||||
|
handle_request(P3D_request *request) {
|
||||||
|
logfile << "handle_request: " << request << "\n";
|
||||||
|
assert(request->_instance == _p3d_inst);
|
||||||
|
|
||||||
|
bool handled = false;
|
||||||
|
|
||||||
|
switch (request->_request_type) {
|
||||||
|
case P3D_RT_stop:
|
||||||
|
logfile << "Got P3D_RT_stop\n";
|
||||||
|
if (_p3d_inst != NULL) {
|
||||||
|
P3D_instance_finish(_p3d_inst);
|
||||||
|
_p3d_inst = NULL;
|
||||||
|
}
|
||||||
|
// Guess the browser doesn't really care.
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P3D_RT_get_url:
|
||||||
|
{
|
||||||
|
logfile << "Got P3D_RT_get_url: " << request->_request._get_url._url
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
PPDownloadRequest *req =
|
||||||
|
new PPDownloadRequest(PPDownloadRequest::RT_user,
|
||||||
|
request->_request._get_url._unique_id);
|
||||||
|
browser->geturlnotify(_npp_instance, request->_request._get_url._url,
|
||||||
|
NULL, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Some request types are not handled.
|
||||||
|
logfile << "Unhandled request: " << request->_request_type << "\n";
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
P3D_request_finish(request, handled);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PPInstance::create_instance
|
// Function: PPInstance::create_instance
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -238,7 +386,7 @@ stream_as_file(NPStream *stream, const char *fname) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PPInstance::
|
void PPInstance::
|
||||||
create_instance() {
|
create_instance() {
|
||||||
if (_inst != NULL) {
|
if (_p3d_inst != NULL) {
|
||||||
// Already created.
|
// Already created.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -263,10 +411,10 @@ create_instance() {
|
|||||||
tokens = &_tokens[0];
|
tokens = &_tokens[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
_inst = P3D_create_instance
|
_p3d_inst = P3D_create_instance
|
||||||
(NULL, _p3d_filename.c_str(), tokens, _tokens.size());
|
(request_ready, this, _p3d_filename.c_str(), tokens, _tokens.size());
|
||||||
|
|
||||||
if (_inst != NULL) {
|
if (_p3d_inst != NULL) {
|
||||||
send_window();
|
send_window();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,7 +428,7 @@ create_instance() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PPInstance::
|
void PPInstance::
|
||||||
send_window() {
|
send_window() {
|
||||||
assert(_inst != NULL);
|
assert(_p3d_inst != NULL);
|
||||||
|
|
||||||
P3D_window_handle parent_window;
|
P3D_window_handle parent_window;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -288,7 +436,7 @@ send_window() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
P3D_instance_setup_window
|
P3D_instance_setup_window
|
||||||
(_inst, P3D_WT_embedded,
|
(_p3d_inst, P3D_WT_toplevel,
|
||||||
_window.x, _window.y, _window.width, _window.height,
|
_window.x, _window.y, _window.width, _window.height,
|
||||||
parent_window);
|
parent_window);
|
||||||
}
|
}
|
||||||
|
@ -35,10 +35,13 @@ public:
|
|||||||
void set_window(NPWindow *window);
|
void set_window(NPWindow *window);
|
||||||
NPError new_stream(NPMIMEType type, NPStream *stream,
|
NPError new_stream(NPMIMEType type, NPStream *stream,
|
||||||
bool seekable, uint16 *stype);
|
bool seekable, uint16 *stype);
|
||||||
|
int write_stream(NPStream *stream, int offset, int len, void *buffer);
|
||||||
NPError destroy_stream(NPStream *stream, NPReason reason);
|
NPError destroy_stream(NPStream *stream, NPReason reason);
|
||||||
void url_notify(const char *url, NPReason reason, void *notifyData);
|
void url_notify(const char *url, NPReason reason, void *notifyData);
|
||||||
void stream_as_file(NPStream *stream, const char *fname);
|
void stream_as_file(NPStream *stream, const char *fname);
|
||||||
|
|
||||||
|
void handle_request(P3D_request *request);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void create_instance();
|
void create_instance();
|
||||||
void send_window();
|
void send_window();
|
||||||
@ -56,7 +59,7 @@ private:
|
|||||||
bool _got_window;
|
bool _got_window;
|
||||||
NPWindow _window;
|
NPWindow _window;
|
||||||
|
|
||||||
P3D_instance *_inst;
|
P3D_instance *_p3d_inst;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "ppInstance.I"
|
#include "ppInstance.I"
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "startup.h"
|
#include "startup.h"
|
||||||
#include "p3d_plugin_config.h"
|
#include "p3d_plugin_config.h"
|
||||||
|
#include "p3d_lock.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
@ -32,6 +33,84 @@ open_logfile() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
UINT _timer = 0;
|
||||||
|
#endif
|
||||||
|
LOCK _timer_lock;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: handle_request_loop
|
||||||
|
// Description: Checks for any new requests from the plugin. This
|
||||||
|
// function is called only in the main thread.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
static void
|
||||||
|
handle_request_loop() {
|
||||||
|
assert(is_plugin_loaded());
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
handle_request_loop();
|
||||||
|
}
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: request_ready
|
||||||
|
// Description: This function is attached as an asyncronous callback
|
||||||
|
// to each instance; it will be notified when the
|
||||||
|
// instance has a request ready. This function may be
|
||||||
|
// called in a sub-thread.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void
|
||||||
|
request_ready(P3D_instance *instance) {
|
||||||
|
logfile
|
||||||
|
<< "request_ready"
|
||||||
|
// << " 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.
|
||||||
|
|
||||||
|
ACQUIRE_LOCK(_timer_lock);
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (_timer == 0) {
|
||||||
|
_timer = SetTimer(NULL, 0, 0, win_timer_func);
|
||||||
|
logfile << "_timer = " << _timer << "\n" << flush;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
RELEASE_LOCK(_timer_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: NP_Initialize
|
// Function: NP_Initialize
|
||||||
// Description: This function is called (almost) before any other
|
// Description: This function is called (almost) before any other
|
||||||
@ -56,9 +135,12 @@ NP_Initialize(NPNetscapeFuncs *browserFuncs,
|
|||||||
|
|
||||||
open_logfile();
|
open_logfile();
|
||||||
logfile << "initializing\n" << flush;
|
logfile << "initializing\n" << flush;
|
||||||
|
// logfile << "main thread = " << GetCurrentThreadId() << "\n";
|
||||||
|
|
||||||
logfile << "browserFuncs = " << browserFuncs << "\n" << flush;
|
logfile << "browserFuncs = " << browserFuncs << "\n" << flush;
|
||||||
|
|
||||||
|
INIT_LOCK(_timer_lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
string plugin_location = "c:/cygwin/home/drose/player/direct/built/lib/p3d_plugin.dll";
|
string plugin_location = "c:/cygwin/home/drose/player/direct/built/lib/p3d_plugin.dll";
|
||||||
@ -116,6 +198,17 @@ NP_GetEntryPoints(NPPluginFuncs *pluginFuncs) {
|
|||||||
NPError OSCALL
|
NPError OSCALL
|
||||||
NP_Shutdown(void) {
|
NP_Shutdown(void) {
|
||||||
logfile << "shutdown\n" << flush;
|
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);
|
||||||
|
|
||||||
unload_plugin();
|
unload_plugin();
|
||||||
|
|
||||||
// Not clear whether there's a return value or not. Some versions
|
// Not clear whether there's a return value or not. Some versions
|
||||||
@ -224,7 +317,10 @@ NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason) {
|
|||||||
int32
|
int32
|
||||||
NPP_WriteReady(NPP instance, NPStream *stream) {
|
NPP_WriteReady(NPP instance, NPStream *stream) {
|
||||||
logfile << "WriteReady\n";
|
logfile << "WriteReady\n";
|
||||||
return 0;
|
// 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.
|
||||||
|
return 0x7fffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -236,8 +332,13 @@ NPP_WriteReady(NPP instance, NPStream *stream) {
|
|||||||
int32
|
int32
|
||||||
NPP_Write(NPP instance, NPStream *stream, int32 offset,
|
NPP_Write(NPP instance, NPStream *stream, int32 offset,
|
||||||
int32 len, void *buffer) {
|
int32 len, void *buffer) {
|
||||||
logfile << "Write\n";
|
logfile << "Write " << stream->url
|
||||||
return 0;
|
<< ", " << len << "\n" << flush;
|
||||||
|
|
||||||
|
PPInstance *inst = (PPInstance *)(instance->pdata);
|
||||||
|
assert(inst != NULL);
|
||||||
|
|
||||||
|
return inst->write_stream(stream, offset, len, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -29,4 +29,6 @@ extern "C" {
|
|||||||
NPError OSCALL NP_Shutdown(void);
|
NPError OSCALL NP_Shutdown(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void request_ready(P3D_instance *instance);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -262,7 +262,7 @@ create_instance(const string &arg, P3D_window_type window_type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
P3D_instance *inst = P3D_create_instance
|
P3D_instance *inst = P3D_create_instance
|
||||||
(NULL, os_p3d_filename.c_str(), tokens, num_tokens);
|
(NULL, NULL, os_p3d_filename.c_str(), tokens, num_tokens);
|
||||||
|
|
||||||
P3D_instance_setup_window
|
P3D_instance_setup_window
|
||||||
(inst, window_type, win_x, win_y, win_width, win_height, parent_window);
|
(inst, window_type, win_x, win_y, win_width, win_height, parent_window);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user