windows crashy
This commit is contained in:
parent
92265c7134
commit
b2906cda8b
|
|
@ -275,6 +275,9 @@ unload_plugin() {
|
|||
cerr << "unload_plugin called\n";
|
||||
|
||||
P3D_finalize();
|
||||
|
||||
// TODO: unloading the DLL causes crashy problems on Windows. Must
|
||||
// be an outstanding pointer or two still uncleaned-up.
|
||||
unload_dso();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,15 @@ PPInstance(NPMIMEType pluginType, NPP instance, uint16 mode,
|
|||
PPInstance::
|
||||
~PPInstance() {
|
||||
logfile
|
||||
<< "destructing " << this << ", " << _p3d_inst << "\n" << flush;
|
||||
<< "destructing PPInstance " << this << "\n";
|
||||
|
||||
#ifdef _WIN32
|
||||
if (_got_window) {
|
||||
// Restore the parent window to its own window handler.
|
||||
HWND hwnd = (HWND)_window.window;
|
||||
SetWindowLongPtr(hwnd, GWL_WNDPROC, _orig_window_proc);
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
if (_p3d_inst != NULL) {
|
||||
P3D_instance_finish(_p3d_inst);
|
||||
|
|
@ -100,7 +108,8 @@ PPInstance::
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PPInstance::
|
||||
set_window(NPWindow *window) {
|
||||
if (window->x == _window.x &&
|
||||
if (_got_window &&
|
||||
window->x == _window.x &&
|
||||
window->y == _window.y &&
|
||||
window->width == _window.width &&
|
||||
window->height == _window.height) {
|
||||
|
|
@ -108,6 +117,25 @@ set_window(NPWindow *window) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (_got_window) {
|
||||
// We don't expect the browser to change the window's parent
|
||||
// on-the-fly.
|
||||
assert(_window.window == window->window);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!_got_window) {
|
||||
_orig_window_proc = NULL;
|
||||
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;
|
||||
_orig_window_proc = SetWindowLongPtr(hwnd, GWL_WNDPROC, (LONG_PTR)window_proc);
|
||||
}
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
_window = *window;
|
||||
_got_window = true;
|
||||
|
||||
|
|
@ -416,6 +444,31 @@ handle_request(P3D_request *request) {
|
|||
P3D_request_finish(request, handled);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PPInstance::handle_request_loop
|
||||
// Access: Public, Static
|
||||
// Description: Checks for any new requests from the plugin, and
|
||||
// dispatches them to the appropriate PPInstance. This
|
||||
// function is called only in the main thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PPInstance::
|
||||
handle_request_loop() {
|
||||
if (!is_plugin_loaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
P3D_instance *p3d_inst = P3D_check_request(false);
|
||||
while (p3d_inst != (P3D_instance *)NULL) {
|
||||
P3D_request *request = P3D_instance_get_request(p3d_inst);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PPInstance::get_panda_script_object
|
||||
// Access: Public
|
||||
|
|
@ -803,3 +856,30 @@ np_variant_to_object(const NPVariant &result) {
|
|||
// Huh, what is this?
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: window_proc
|
||||
// Access: Private, Static
|
||||
// Description: We bind this function to the parent window we were
|
||||
// given in set_window, so we can spin the request_loop
|
||||
// when needed. This is only in the Windows case; other
|
||||
// platforms rely on explicit windows events.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LONG PPInstance::
|
||||
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;
|
||||
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ public:
|
|||
void stream_as_file(NPStream *stream, const char *fname);
|
||||
|
||||
void handle_request(P3D_request *request);
|
||||
static void handle_request_loop();
|
||||
|
||||
NPObject *get_panda_script_object();
|
||||
|
||||
|
|
@ -66,6 +67,11 @@ private:
|
|||
void show_np_variant(const NPVariant &result);
|
||||
P3D_object *np_variant_to_object(const NPVariant &result);
|
||||
|
||||
#ifdef _WIN32
|
||||
static LONG
|
||||
window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
#endif // _WIN32
|
||||
|
||||
private:
|
||||
NPP _npp_instance;
|
||||
unsigned int _npp_mode;
|
||||
|
|
@ -81,6 +87,9 @@ private:
|
|||
|
||||
bool _got_window;
|
||||
NPWindow _window;
|
||||
#ifdef _WIN32
|
||||
LONG_PTR _orig_window_proc;
|
||||
#endif // _WIN32
|
||||
|
||||
PPPandaObject *_script_object;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,53 +34,6 @@ open_logfile() {
|
|||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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() {
|
||||
if (!is_plugin_loaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
P3D_instance *p3d_inst = P3D_check_request(false);
|
||||
while (p3d_inst != (P3D_instance *)NULL) {
|
||||
P3D_request *request = P3D_instance_get_request(p3d_inst);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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;
|
||||
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: request_ready
|
||||
// Description: This function is attached as an asynchronous callback
|
||||
|
|
@ -241,16 +194,6 @@ NPP_SetWindow(NPP instance, NPWindow *window) {
|
|||
<< ", " << window->width << ", " << window->height
|
||||
<< "\n" << flush;
|
||||
|
||||
#ifdef _WIN32
|
||||
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);
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
PPInstance *inst = (PPInstance *)(instance->pdata);
|
||||
assert(inst != NULL);
|
||||
inst->set_window(window);
|
||||
|
|
@ -367,7 +310,7 @@ NPP_HandleEvent(NPP instance, void *event) {
|
|||
// logfile << "HandleEvent\n";
|
||||
|
||||
// Here's a fine opportunity to check for new requests.
|
||||
handle_request_loop();
|
||||
PPInstance::handle_request_loop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue