mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
finish workaround for Vista keyboard issue
This commit is contained in:
parent
8061092d8e
commit
13877e26b1
@ -13,11 +13,14 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "binaryXml.h"
|
#include "binaryXml.h"
|
||||||
|
#include "p3d_lock.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
static const bool debug_xml_output = false;
|
static const bool debug_xml_output = false;
|
||||||
|
|
||||||
|
static LOCK xml_lock;
|
||||||
|
static bool xml_lock_initialized = false;
|
||||||
|
|
||||||
#define DO_BINARY_XML 1
|
#define DO_BINARY_XML 1
|
||||||
|
|
||||||
enum NodeType {
|
enum NodeType {
|
||||||
@ -251,6 +254,11 @@ read_xml_node(istream &in, char *&buffer, size_t &buffer_length,
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void
|
void
|
||||||
write_xml(ostream &out, TiXmlDocument *doc, ostream &logfile) {
|
write_xml(ostream &out, TiXmlDocument *doc, ostream &logfile) {
|
||||||
|
if (!xml_lock_initialized) {
|
||||||
|
INIT_LOCK(xml_lock);
|
||||||
|
}
|
||||||
|
ACQUIRE_LOCK(xml_lock);
|
||||||
|
|
||||||
#ifdef DO_BINARY_XML
|
#ifdef DO_BINARY_XML
|
||||||
// Binary write.
|
// Binary write.
|
||||||
write_xml_node(out, doc);
|
write_xml_node(out, doc);
|
||||||
@ -274,6 +282,8 @@ write_xml(ostream &out, TiXmlDocument *doc, ostream &logfile) {
|
|||||||
logout << "sent: " << *doc << "\n";
|
logout << "sent: " << *doc << "\n";
|
||||||
logfile << logout.str() << flush;
|
logfile << logout.str() << flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RELEASE_LOCK(xml_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -291,6 +301,11 @@ write_xml(ostream &out, TiXmlDocument *doc, ostream &logfile) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
TiXmlDocument *
|
TiXmlDocument *
|
||||||
read_xml(istream &in, ostream &logfile) {
|
read_xml(istream &in, ostream &logfile) {
|
||||||
|
if (!xml_lock_initialized) {
|
||||||
|
INIT_LOCK(xml_lock);
|
||||||
|
}
|
||||||
|
ACQUIRE_LOCK(xml_lock);
|
||||||
|
|
||||||
#if DO_BINARY_XML
|
#if DO_BINARY_XML
|
||||||
// binary read.
|
// binary read.
|
||||||
size_t buffer_length = 128;
|
size_t buffer_length = 128;
|
||||||
@ -298,6 +313,7 @@ read_xml(istream &in, ostream &logfile) {
|
|||||||
TiXmlNode *xnode = read_xml_node(in, buffer, buffer_length, logfile);
|
TiXmlNode *xnode = read_xml_node(in, buffer, buffer_length, logfile);
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
if (xnode == NULL) {
|
if (xnode == NULL) {
|
||||||
|
RELEASE_LOCK(xml_lock);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,6 +326,7 @@ read_xml(istream &in, ostream &logfile) {
|
|||||||
in >> *doc;
|
in >> *doc;
|
||||||
if (in.fail() || in.eof()) {
|
if (in.fail() || in.eof()) {
|
||||||
delete doc;
|
delete doc;
|
||||||
|
RELEASE_LOCK(xml_lock);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -322,5 +339,6 @@ read_xml(istream &in, ostream &logfile) {
|
|||||||
logfile << logout.str() << flush;
|
logfile << logout.str() << flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RELEASE_LOCK(xml_lock);
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
@ -1426,7 +1426,6 @@ void P3DInstance::
|
|||||||
handle_notify_request(const string &message) {
|
handle_notify_request(const string &message) {
|
||||||
// We look for certain notify events that have particular meaning
|
// We look for certain notify events that have particular meaning
|
||||||
// to this instance.
|
// to this instance.
|
||||||
nout << "Got notify: " << message << "\n";
|
|
||||||
if (message == "onpythonload") {
|
if (message == "onpythonload") {
|
||||||
// Once Python is up and running, we can get the actual main
|
// Once Python is up and running, we can get the actual main
|
||||||
// object from the Python side, and merge it with our own.
|
// object from the Python side, and merge it with our own.
|
||||||
@ -1459,13 +1458,13 @@ handle_notify_request(const string &message) {
|
|||||||
|
|
||||||
} else if (message == "onwindowopen") {
|
} else if (message == "onwindowopen") {
|
||||||
// The process told us that it just succesfully opened its
|
// The process told us that it just succesfully opened its
|
||||||
// window. Tear down the splash window.
|
// window. Hide the splash window.
|
||||||
_instance_window_opened = true;
|
_instance_window_opened = true;
|
||||||
if (_splash_window != NULL) {
|
if (_splash_window != NULL) {
|
||||||
delete _splash_window;
|
_splash_window->set_visible(false);
|
||||||
_splash_window = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Guess we won't be using these images any more.
|
||||||
for (int i = 0; i < (int)IT_num_image_types; ++i) {
|
for (int i = 0; i < (int)IT_num_image_types; ++i) {
|
||||||
_image_files[i].cleanup();
|
_image_files[i].cleanup();
|
||||||
}
|
}
|
||||||
@ -1497,7 +1496,9 @@ handle_notify_request(const string &message) {
|
|||||||
auth_finished_main_thread();
|
auth_finished_main_thread();
|
||||||
|
|
||||||
} else if (message == "keyboardfocus") {
|
} else if (message == "keyboardfocus") {
|
||||||
request_keyboard_focus();
|
if (_splash_window != NULL) {
|
||||||
|
_splash_window->request_keyboard_focus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1597,19 +1598,6 @@ handle_script_request(const string &operation, P3D_object *object,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: P3DInstance::request_keyboard_focus
|
|
||||||
// Access: Private
|
|
||||||
// Description: The Panda window is asking us to manage keyboard
|
|
||||||
// focus in proxy for it. This is used on Vista, where
|
|
||||||
// the Panda window may be disallowed from directly
|
|
||||||
// assigning itself keyboard focus.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void P3DInstance::
|
|
||||||
request_keyboard_focus() {
|
|
||||||
nout << "request_keyboard_focus\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DInstance::make_splash_window
|
// Function: P3DInstance::make_splash_window
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -1618,8 +1606,24 @@ request_keyboard_focus() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DInstance::
|
void P3DInstance::
|
||||||
make_splash_window() {
|
make_splash_window() {
|
||||||
if (_splash_window != NULL || _instance_window_opened) {
|
// Should we make the splash window visible?
|
||||||
// Already got one, or we're already showing the real instance.
|
bool make_visible = true;
|
||||||
|
if (_instance_window_opened) {
|
||||||
|
// Not once we've opened the main window.
|
||||||
|
make_visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_wparams.get_window_type() != P3D_WT_embedded &&
|
||||||
|
!_stuff_to_download && _auto_start && _p3d_trusted) {
|
||||||
|
// If it's a toplevel or fullscreen window, then we don't want a
|
||||||
|
// splash window unless we have stuff to download, or a button to
|
||||||
|
// display.
|
||||||
|
make_visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_splash_window != NULL) {
|
||||||
|
// Already got one.
|
||||||
|
_splash_window->set_visible(make_visible);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!_got_wparams) {
|
if (!_got_wparams) {
|
||||||
@ -1630,15 +1634,8 @@ make_splash_window() {
|
|||||||
// We're hidden, and so is the splash window.
|
// We're hidden, and so is the splash window.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_wparams.get_window_type() != P3D_WT_embedded &&
|
|
||||||
!_stuff_to_download && _auto_start && _p3d_trusted) {
|
|
||||||
// If it's a toplevel or fullscreen window, then we don't want a
|
|
||||||
// splash window unless we have stuff to download, or a button to
|
|
||||||
// display.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_splash_window = new SplashWindowType(this);
|
_splash_window = new SplashWindowType(this, make_visible);
|
||||||
_splash_window->set_wparams(_wparams);
|
_splash_window->set_wparams(_wparams);
|
||||||
_splash_window->set_install_label(_install_label);
|
_splash_window->set_install_label(_install_label);
|
||||||
|
|
||||||
|
@ -162,7 +162,6 @@ private:
|
|||||||
void handle_script_request(const string &operation, P3D_object *object,
|
void handle_script_request(const string &operation, P3D_object *object,
|
||||||
const string &property_name, P3D_object *value,
|
const string &property_name, P3D_object *value,
|
||||||
bool needs_response, int unique_id);
|
bool needs_response, int unique_id);
|
||||||
void request_keyboard_focus();
|
|
||||||
|
|
||||||
void make_splash_window();
|
void make_splash_window();
|
||||||
void set_background_image(ImageType image_type);
|
void set_background_image(ImageType image_type);
|
||||||
|
@ -29,8 +29,8 @@
|
|||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
P3DOsxSplashWindow::
|
P3DOsxSplashWindow::
|
||||||
P3DOsxSplashWindow(P3DInstance *inst) :
|
P3DOsxSplashWindow(P3DInstance *inst, bool make_visible) :
|
||||||
P3DSplashWindow(inst)
|
P3DSplashWindow(inst, make_visible)
|
||||||
{
|
{
|
||||||
_install_progress = 0;
|
_install_progress = 0;
|
||||||
_got_wparams = false;
|
_got_wparams = false;
|
||||||
@ -226,6 +226,9 @@ handle_event(P3D_event_data event) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DOsxSplashWindow::
|
void P3DOsxSplashWindow::
|
||||||
refresh() {
|
refresh() {
|
||||||
|
if (!_visible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (_toplevel_window != NULL) {
|
if (_toplevel_window != NULL) {
|
||||||
Rect r = { 0, 0, _win_height, _win_width };
|
Rect r = { 0, 0, _win_height, _win_width };
|
||||||
InvalWindowRect(_toplevel_window, &r);
|
InvalWindowRect(_toplevel_window, &r);
|
||||||
@ -242,7 +245,7 @@ refresh() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DOsxSplashWindow::
|
void P3DOsxSplashWindow::
|
||||||
paint_window() {
|
paint_window() {
|
||||||
if (!_got_wparams) {
|
if (!_visible) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class P3DOsxSplashWindow : public P3DSplashWindow {
|
class P3DOsxSplashWindow : public P3DSplashWindow {
|
||||||
public:
|
public:
|
||||||
P3DOsxSplashWindow(P3DInstance *inst);
|
P3DOsxSplashWindow(P3DInstance *inst, bool make_visible);
|
||||||
virtual ~P3DOsxSplashWindow();
|
virtual ~P3DOsxSplashWindow();
|
||||||
|
|
||||||
virtual void set_wparams(const P3DWindowParams &wparams);
|
virtual void set_wparams(const P3DWindowParams &wparams);
|
||||||
|
@ -403,8 +403,6 @@ run_python() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void P3DPythonRun::
|
void P3DPythonRun::
|
||||||
request_keyboard_focus(P3DCInstance *inst) {
|
request_keyboard_focus(P3DCInstance *inst) {
|
||||||
cerr << "requesting keyboard focus\n";
|
|
||||||
|
|
||||||
TiXmlDocument doc;
|
TiXmlDocument doc;
|
||||||
TiXmlElement *xrequest = new TiXmlElement("request");
|
TiXmlElement *xrequest = new TiXmlElement("request");
|
||||||
xrequest->SetAttribute("instance_id", inst->get_instance_id());
|
xrequest->SetAttribute("instance_id", inst->get_instance_id());
|
||||||
@ -509,6 +507,18 @@ handle_command(TiXmlDocument *doc) {
|
|||||||
setup_window(instance_id, xwparams);
|
setup_window(instance_id, xwparams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (strcmp(cmd, "windows_message") == 0) {
|
||||||
|
assert(!needs_response);
|
||||||
|
// This is a special message that we use to proxy keyboard
|
||||||
|
// events from the parent process down into Panda, a necessary
|
||||||
|
// hack on Vista.
|
||||||
|
int instance_id = 0, msg = 0, wparam = 0, lparam = 0;
|
||||||
|
xcommand->Attribute("instance_id", &instance_id);
|
||||||
|
xcommand->Attribute("msg", &msg);
|
||||||
|
xcommand->Attribute("wparam", &wparam);
|
||||||
|
xcommand->Attribute("lparam", &lparam);
|
||||||
|
send_windows_message(instance_id, msg, wparam, lparam);
|
||||||
|
|
||||||
} else if (strcmp(cmd, "exit") == 0) {
|
} else if (strcmp(cmd, "exit") == 0) {
|
||||||
assert(!needs_response);
|
assert(!needs_response);
|
||||||
terminate_session();
|
terminate_session();
|
||||||
@ -1362,6 +1372,25 @@ setup_window(P3DCInstance *inst, TiXmlElement *xwparams) {
|
|||||||
Py_XDECREF(result);
|
Py_XDECREF(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DPythonRun::send_windows_message
|
||||||
|
// Access: Public
|
||||||
|
// Description: This is used to deliver a windows keyboard message to
|
||||||
|
// the Panda process from the parent process, a
|
||||||
|
// necessary hack on Vista.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DPythonRun::
|
||||||
|
send_windows_message(int id, unsigned int msg, int wparam, int lparam) {
|
||||||
|
Instances::iterator ii = _instances.find(id);
|
||||||
|
if (ii == _instances.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
P3DCInstance *inst = (*ii).second;
|
||||||
|
if (inst->_parent_window_handle != (WindowHandle *)NULL) {
|
||||||
|
inst->_parent_window_handle->send_windows_message(msg, wparam, lparam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DPythonRun::terminate_session
|
// Function: P3DPythonRun::terminate_session
|
||||||
@ -1719,7 +1748,7 @@ rt_thread_run() {
|
|||||||
P3DPythonRun::P3DWindowHandle::
|
P3DPythonRun::P3DWindowHandle::
|
||||||
P3DWindowHandle(P3DPythonRun *p3dpython, P3DCInstance *inst,
|
P3DWindowHandle(P3DPythonRun *p3dpython, P3DCInstance *inst,
|
||||||
const WindowHandle ©) :
|
const WindowHandle ©) :
|
||||||
WindowHandle(copy.get_os_handle()),
|
WindowHandle(copy),
|
||||||
_p3dpython(p3dpython),
|
_p3dpython(p3dpython),
|
||||||
_inst(inst)
|
_inst(inst)
|
||||||
{
|
{
|
||||||
|
@ -101,6 +101,8 @@ private:
|
|||||||
void setup_window(int id, TiXmlElement *xwparams);
|
void setup_window(int id, TiXmlElement *xwparams);
|
||||||
void setup_window(P3DCInstance *inst, TiXmlElement *xwparams);
|
void setup_window(P3DCInstance *inst, TiXmlElement *xwparams);
|
||||||
|
|
||||||
|
void send_windows_message(int id, unsigned int msg, int wparam, int lparam);
|
||||||
|
|
||||||
void terminate_session();
|
void terminate_session();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -108,7 +110,7 @@ private:
|
|||||||
PyObject *xml_to_pyobj(TiXmlElement *xvalue);
|
PyObject *xml_to_pyobj(TiXmlElement *xvalue);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// This subclass of P3DWindowHandle is associated with the parent
|
// This subclass of WindowHandle is associated with the parent
|
||||||
// window we are given by the parent process. We use it to add
|
// window we are given by the parent process. We use it to add
|
||||||
// hooks for communicating with the parent window, for instance to
|
// hooks for communicating with the parent window, for instance to
|
||||||
// ask for the parent window to manage keyboard focus when
|
// ask for the parent window to manage keyboard focus when
|
||||||
@ -118,13 +120,13 @@ private:
|
|||||||
P3DWindowHandle(P3DPythonRun *p3dpython, P3DCInstance *inst,
|
P3DWindowHandle(P3DPythonRun *p3dpython, P3DCInstance *inst,
|
||||||
const WindowHandle ©);
|
const WindowHandle ©);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void request_keyboard_focus(WindowHandle *child);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
P3DPythonRun *_p3dpython;
|
P3DPythonRun *_p3dpython;
|
||||||
P3DCInstance *_inst;
|
P3DCInstance *_inst;
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void request_keyboard_focus(WindowHandle *child);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static TypeHandle get_class_type() {
|
static TypeHandle get_class_type() {
|
||||||
return _type_handle;
|
return _type_handle;
|
||||||
|
@ -583,6 +583,29 @@ p3dobj_to_xml(P3D_object *obj) {
|
|||||||
return xvalue;
|
return xvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DSession::send_windows_message
|
||||||
|
// Access: Public
|
||||||
|
// Description: This is called by the splash window to deliver a
|
||||||
|
// windows keyboard message to the Panda process. It
|
||||||
|
// will be called in a sub-thread, but that's OK, since
|
||||||
|
// write_xml() supports locking.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DSession::
|
||||||
|
send_windows_message(P3DInstance *inst, unsigned int msg, int wparam, int lparam) {
|
||||||
|
if (_p3dpython_started) {
|
||||||
|
TiXmlDocument doc;
|
||||||
|
TiXmlElement *xcommand = new TiXmlElement("command");
|
||||||
|
xcommand->SetAttribute("cmd", "windows_message");
|
||||||
|
xcommand->SetAttribute("instance_id", inst->get_instance_id());
|
||||||
|
xcommand->SetAttribute("msg", msg);
|
||||||
|
xcommand->SetAttribute("wparam", wparam);
|
||||||
|
xcommand->SetAttribute("lparam", lparam);
|
||||||
|
doc.LinkEndChild(xcommand);
|
||||||
|
write_xml(_pipe_write, &doc, nout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DSession::signal_request_ready
|
// Function: P3DSession::signal_request_ready
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -54,6 +54,8 @@ public:
|
|||||||
TiXmlDocument *command_and_response(TiXmlDocument *command);
|
TiXmlDocument *command_and_response(TiXmlDocument *command);
|
||||||
P3D_object *xml_to_p3dobj(const TiXmlElement *xvalue);
|
P3D_object *xml_to_p3dobj(const TiXmlElement *xvalue);
|
||||||
TiXmlElement *p3dobj_to_xml(P3D_object *obj);
|
TiXmlElement *p3dobj_to_xml(P3D_object *obj);
|
||||||
|
void send_windows_message(P3DInstance *inst, unsigned int msg,
|
||||||
|
int wparam, int lparam);
|
||||||
|
|
||||||
void signal_request_ready(P3DInstance *inst);
|
void signal_request_ready(P3DInstance *inst);
|
||||||
|
|
||||||
|
@ -49,11 +49,12 @@ METHODDEF(void) my_error_exit (j_common_ptr cinfo) {
|
|||||||
// them both into this class for reference.
|
// them both into this class for reference.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
P3DSplashWindow::
|
P3DSplashWindow::
|
||||||
P3DSplashWindow(P3DInstance *inst) :
|
P3DSplashWindow(P3DInstance *inst, bool make_visible) :
|
||||||
_inst(inst),
|
_inst(inst),
|
||||||
_fparams(inst->get_fparams()),
|
_fparams(inst->get_fparams()),
|
||||||
_wparams(inst->get_wparams())
|
_wparams(inst->get_wparams())
|
||||||
{
|
{
|
||||||
|
_visible = make_visible;
|
||||||
_button_width = 0;
|
_button_width = 0;
|
||||||
_button_height = 0;
|
_button_height = 0;
|
||||||
_button_x = 0;
|
_button_x = 0;
|
||||||
@ -87,6 +88,20 @@ set_wparams(const P3DWindowParams &wparams) {
|
|||||||
_wparams = wparams;
|
_wparams = wparams;
|
||||||
_win_width = _wparams.get_win_width();
|
_win_width = _wparams.get_win_width();
|
||||||
_win_height = _wparams.get_win_height();
|
_win_height = _wparams.get_win_height();
|
||||||
|
_visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DSplashWindow::set_visible
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Makes the splash window visible or invisible, so as
|
||||||
|
// not to compete with the embedded Panda window in the
|
||||||
|
// same space.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DSplashWindow::
|
||||||
|
set_visible(bool visible) {
|
||||||
|
nout << "P3DSplashWindow::set_visible(" << visible << ")\n";
|
||||||
|
_visible = visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -152,6 +167,18 @@ set_button_active(bool flag) {
|
|||||||
set_mouse_data(_mouse_x, _mouse_y, _mouse_down);
|
set_mouse_data(_mouse_x, _mouse_y, _mouse_down);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DSplashWindow::request_keyboard_focus
|
||||||
|
// Access: Private
|
||||||
|
// Description: The Panda window is asking us to manage keyboard
|
||||||
|
// focus in proxy for it. This is used on Vista, where
|
||||||
|
// the Panda window may be disallowed from directly
|
||||||
|
// assigning itself keyboard focus.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DSplashWindow::
|
||||||
|
request_keyboard_focus() {
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DSplashWindow::read_image_data
|
// Function: P3DSplashWindow::read_image_data
|
||||||
// Access: Protected
|
// Access: Protected
|
||||||
|
@ -33,7 +33,7 @@ class P3DInstance;
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class P3DSplashWindow {
|
class P3DSplashWindow {
|
||||||
public:
|
public:
|
||||||
P3DSplashWindow(P3DInstance *inst);
|
P3DSplashWindow(P3DInstance *inst, bool make_visible);
|
||||||
virtual ~P3DSplashWindow();
|
virtual ~P3DSplashWindow();
|
||||||
|
|
||||||
inline const P3DFileParams &get_fparams() const;
|
inline const P3DFileParams &get_fparams() const;
|
||||||
@ -41,6 +41,8 @@ public:
|
|||||||
virtual void set_wparams(const P3DWindowParams &wparams);
|
virtual void set_wparams(const P3DWindowParams &wparams);
|
||||||
inline const P3DWindowParams &get_wparams() const;
|
inline const P3DWindowParams &get_wparams() const;
|
||||||
|
|
||||||
|
virtual void set_visible(bool visible);
|
||||||
|
|
||||||
enum ImagePlacement {
|
enum ImagePlacement {
|
||||||
IP_background,
|
IP_background,
|
||||||
IP_button_ready,
|
IP_button_ready,
|
||||||
@ -57,6 +59,7 @@ public:
|
|||||||
virtual bool handle_event(P3D_event_data event);
|
virtual bool handle_event(P3D_event_data event);
|
||||||
|
|
||||||
virtual void set_button_active(bool flag);
|
virtual void set_button_active(bool flag);
|
||||||
|
virtual void request_keyboard_focus();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// This ImageData base class provides minimal functionality for
|
// This ImageData base class provides minimal functionality for
|
||||||
@ -96,6 +99,7 @@ protected:
|
|||||||
P3DFileParams _fparams;
|
P3DFileParams _fparams;
|
||||||
P3DWindowParams _wparams;
|
P3DWindowParams _wparams;
|
||||||
int _win_width, _win_height;
|
int _win_width, _win_height;
|
||||||
|
bool _visible;
|
||||||
|
|
||||||
// The region of the window for accepting button clicks.
|
// The region of the window for accepting button clicks.
|
||||||
int _button_width, _button_height;
|
int _button_width, _button_height;
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#ifndef WM_MOUSEWHEEL
|
||||||
|
#define WM_MOUSEWHEEL 0x20a
|
||||||
|
#endif
|
||||||
|
|
||||||
bool P3DWinSplashWindow::_registered_window_class = false;
|
bool P3DWinSplashWindow::_registered_window_class = false;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -24,8 +28,8 @@ bool P3DWinSplashWindow::_registered_window_class = false;
|
|||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
P3DWinSplashWindow::
|
P3DWinSplashWindow::
|
||||||
P3DWinSplashWindow(P3DInstance *inst) :
|
P3DWinSplashWindow(P3DInstance *inst, bool make_visible) :
|
||||||
P3DSplashWindow(inst)
|
P3DSplashWindow(inst, make_visible)
|
||||||
{
|
{
|
||||||
_thread = NULL;
|
_thread = NULL;
|
||||||
_thread_id = 0;
|
_thread_id = 0;
|
||||||
@ -36,6 +40,9 @@ P3DWinSplashWindow(P3DInstance *inst) :
|
|||||||
|
|
||||||
_drawn_bstate = BS_hidden;
|
_drawn_bstate = BS_hidden;
|
||||||
_drawn_progress = 0.0;
|
_drawn_progress = 0.0;
|
||||||
|
_focus_seq = 0;
|
||||||
|
|
||||||
|
_request_focus_tick = 0;
|
||||||
|
|
||||||
INIT_LOCK(_install_lock);
|
INIT_LOCK(_install_lock);
|
||||||
}
|
}
|
||||||
@ -68,6 +75,24 @@ set_wparams(const P3DWindowParams &wparams) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DWinSplashWindow::set_visible
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Makes the splash window visible or invisible, so as
|
||||||
|
// not to compete with the embedded Panda window in the
|
||||||
|
// same space.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DWinSplashWindow::
|
||||||
|
set_visible(bool visible) {
|
||||||
|
P3DSplashWindow::set_visible(visible);
|
||||||
|
|
||||||
|
if (_visible) {
|
||||||
|
ShowWindow(_hwnd, SW_SHOWNORMAL);
|
||||||
|
} else {
|
||||||
|
ShowWindow(_hwnd, SW_HIDE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DWinSplashWindow::set_image_filename
|
// Function: P3DWinSplashWindow::set_image_filename
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
@ -166,6 +191,30 @@ set_install_progress(double install_progress) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: P3DWinSplashWindow::request_keyboard_focus
|
||||||
|
// Access: Private
|
||||||
|
// Description: The Panda window is asking us to manage keyboard
|
||||||
|
// focus in proxy for it. This is used on Vista, where
|
||||||
|
// the Panda window may be disallowed from directly
|
||||||
|
// assigning itself keyboard focus.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void P3DWinSplashWindow::
|
||||||
|
request_keyboard_focus() {
|
||||||
|
// Store the time at which we last requested focus.
|
||||||
|
_request_focus_tick = GetTickCount();
|
||||||
|
|
||||||
|
// Increment the _focus_seq to tell the thread to call SetFocus().
|
||||||
|
ACQUIRE_LOCK(_install_lock);
|
||||||
|
++_focus_seq;
|
||||||
|
RELEASE_LOCK(_install_lock);
|
||||||
|
|
||||||
|
if (_thread_id != 0) {
|
||||||
|
// Post a silly message to spin the message loop.
|
||||||
|
PostThreadMessage(_thread_id, WM_USER, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: P3DWinSplashWindow::register_window_class
|
// Function: P3DWinSplashWindow::register_window_class
|
||||||
// Access: Public, Static
|
// Access: Public, Static
|
||||||
@ -277,6 +326,7 @@ void P3DWinSplashWindow::
|
|||||||
thread_run() {
|
thread_run() {
|
||||||
make_window();
|
make_window();
|
||||||
|
|
||||||
|
int last_focus_seq = 0;
|
||||||
MSG msg;
|
MSG msg;
|
||||||
int retval;
|
int retval;
|
||||||
retval = GetMessage(&msg, NULL, 0, 0);
|
retval = GetMessage(&msg, NULL, 0, 0);
|
||||||
@ -312,6 +362,14 @@ thread_run() {
|
|||||||
_drawn_bstate = _bstate;
|
_drawn_bstate = _bstate;
|
||||||
InvalidateRect(_hwnd, NULL, TRUE);
|
InvalidateRect(_hwnd, NULL, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_focus_seq != last_focus_seq) {
|
||||||
|
last_focus_seq = _focus_seq;
|
||||||
|
if (SetFocus(_hwnd) == NULL && GetLastError() != 0) {
|
||||||
|
nout << "SetFocus(" << _hwnd << ") failed: " << GetLastError() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RELEASE_LOCK(_install_lock);
|
RELEASE_LOCK(_install_lock);
|
||||||
|
|
||||||
retval = GetMessage(&msg, NULL, 0, 0);
|
retval = GetMessage(&msg, NULL, 0, 0);
|
||||||
@ -396,7 +454,13 @@ make_window() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetWindowLongPtr(_hwnd, GWLP_USERDATA, (LONG_PTR)this);
|
SetWindowLongPtr(_hwnd, GWLP_USERDATA, (LONG_PTR)this);
|
||||||
ShowWindow(_hwnd, SW_SHOWNORMAL);
|
nout << "Created splash window " << _hwnd << "\n";
|
||||||
|
|
||||||
|
if (_visible) {
|
||||||
|
ShowWindow(_hwnd, SW_SHOWNORMAL);
|
||||||
|
} else {
|
||||||
|
ShowWindow(_hwnd, SW_HIDE);
|
||||||
|
}
|
||||||
|
|
||||||
_blue_brush = CreateSolidBrush(RGB(108, 165, 224));
|
_blue_brush = CreateSolidBrush(RGB(108, 165, 224));
|
||||||
}
|
}
|
||||||
@ -802,6 +866,41 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||||||
set_mouse_data(_mouse_x, _mouse_y, false);
|
set_mouse_data(_mouse_x, _mouse_y, false);
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WM_KILLFOCUS:
|
||||||
|
// Someone on the desktop is playing games with us. It keeps
|
||||||
|
// wanting to grab the keyboard focus back immediately after we
|
||||||
|
// successfully call SetFocus(). Well, we really mean it, darn it
|
||||||
|
// all. If we got a WM_KILLFOCUS within a few milliseconds of
|
||||||
|
// calling SetFocus(), well, call SetFocus() again, until it
|
||||||
|
// sticks.
|
||||||
|
{
|
||||||
|
int elapsed = GetTickCount() - _request_focus_tick;
|
||||||
|
if (elapsed < 200) {
|
||||||
|
if (SetFocus(_hwnd) == NULL && GetLastError() != 0) {
|
||||||
|
nout << "Secondary SetFocus failed: " << GetLastError() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Keyboard events that are to be proxied to the Panda window.
|
||||||
|
case WM_MOUSEWHEEL:
|
||||||
|
case WM_IME_SETCONTEXT:
|
||||||
|
case WM_IME_NOTIFY:
|
||||||
|
case WM_IME_STARTCOMPOSITION:
|
||||||
|
case WM_IME_ENDCOMPOSITION:
|
||||||
|
case WM_IME_COMPOSITION:
|
||||||
|
case WM_CHAR:
|
||||||
|
case WM_SYSKEYDOWN:
|
||||||
|
case WM_SYSCOMMAND:
|
||||||
|
case WM_KEYDOWN:
|
||||||
|
case WM_SYSKEYUP:
|
||||||
|
case WM_KEYUP:
|
||||||
|
if (_inst->get_session() != NULL) {
|
||||||
|
_inst->get_session()->send_windows_message(_inst, msg, wparam, lparam);
|
||||||
|
}
|
||||||
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||||
|
@ -31,14 +31,17 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class P3DWinSplashWindow : public P3DSplashWindow {
|
class P3DWinSplashWindow : public P3DSplashWindow {
|
||||||
public:
|
public:
|
||||||
P3DWinSplashWindow(P3DInstance *inst);
|
P3DWinSplashWindow(P3DInstance *inst, bool make_visible);
|
||||||
virtual ~P3DWinSplashWindow();
|
virtual ~P3DWinSplashWindow();
|
||||||
|
|
||||||
virtual void set_wparams(const P3DWindowParams &wparams);
|
virtual void set_wparams(const P3DWindowParams &wparams);
|
||||||
|
virtual void set_visible(bool visible);
|
||||||
|
|
||||||
virtual void set_image_filename(const string &image_filename,
|
virtual void set_image_filename(const string &image_filename,
|
||||||
ImagePlacement image_placement);
|
ImagePlacement image_placement);
|
||||||
virtual void set_install_label(const string &install_label);
|
virtual void set_install_label(const string &install_label);
|
||||||
virtual void set_install_progress(double install_progress);
|
virtual void set_install_progress(double install_progress);
|
||||||
|
virtual void request_keyboard_focus();
|
||||||
|
|
||||||
static void register_window_class();
|
static void register_window_class();
|
||||||
static void unregister_window_class();
|
static void unregister_window_class();
|
||||||
@ -92,6 +95,9 @@ private:
|
|||||||
ButtonState _drawn_bstate;
|
ButtonState _drawn_bstate;
|
||||||
string _drawn_label;
|
string _drawn_label;
|
||||||
double _drawn_progress;
|
double _drawn_progress;
|
||||||
|
int _focus_seq;
|
||||||
|
|
||||||
|
int _request_focus_tick;
|
||||||
|
|
||||||
bool _thread_continue;
|
bool _thread_continue;
|
||||||
bool _thread_running;
|
bool _thread_running;
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class P3DX11SplashWindow : public P3DSplashWindow {
|
class P3DX11SplashWindow : public P3DSplashWindow {
|
||||||
public:
|
public:
|
||||||
P3DX11SplashWindow(P3DInstance *inst);
|
P3DX11SplashWindow(P3DInstance *inst, bool make_visible);
|
||||||
virtual ~P3DX11SplashWindow();
|
virtual ~P3DX11SplashWindow();
|
||||||
|
|
||||||
virtual void set_wparams(const P3DWindowParams &wparams);
|
virtual void set_wparams(const P3DWindowParams &wparams);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user