mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
latest merges from Schell Games
This commit is contained in:
parent
7f97f4ed46
commit
28d62c55ef
@ -38,6 +38,7 @@ Options:
|
||||
-r remove the default library list; instrument only named libraries
|
||||
-O no C++ comments or assertion statements
|
||||
-n Don't use squeezeTool to squeeze the result into one .pyz file
|
||||
-s Don't delete source files after squeezing
|
||||
|
||||
Any additional names listed on the command line are taken to be names
|
||||
of libraries that are to be instrumented.
|
||||
@ -50,7 +51,8 @@ extensionsDir = ''
|
||||
interrogateLib = ''
|
||||
codeLibs = []
|
||||
etcPath = []
|
||||
doSqueeze = 1
|
||||
doSqueeze = True
|
||||
deleteSourceAfterSqueeze = True
|
||||
|
||||
def doGetopts():
|
||||
global outputDir
|
||||
@ -58,6 +60,7 @@ def doGetopts():
|
||||
global interrogateLib
|
||||
global codeLibs
|
||||
global doSqueeze
|
||||
global deleteSourceAfterSqueeze
|
||||
global etcPath
|
||||
|
||||
# These options are allowed but are flagged as warnings (they are
|
||||
@ -73,7 +76,7 @@ def doGetopts():
|
||||
|
||||
# Extract the args the user passed in
|
||||
try:
|
||||
opts, pargs = getopt.getopt(sys.argv[1:], 'hvOd:x:i:e:rngtpo')
|
||||
opts, pargs = getopt.getopt(sys.argv[1:], 'hvOd:x:i:e:rnsgtpo')
|
||||
except Exception, e:
|
||||
# User passed in a bad option, print the error and the help, then exit
|
||||
print e
|
||||
@ -105,7 +108,9 @@ def doGetopts():
|
||||
FFIConstants.wantComments = 0
|
||||
FFIConstants.wantTypeChecking = 0
|
||||
elif (flag == '-n'):
|
||||
doSqueeze = 0
|
||||
doSqueeze = False
|
||||
elif (flag == '-s'):
|
||||
deleteSourceAfterSqueeze = False
|
||||
elif (flag in ['-g', '-t', '-p', '-o']):
|
||||
FFIConstants.notify.warning("option is deprecated: %s" % (flag))
|
||||
|
||||
@ -191,4 +196,4 @@ def run():
|
||||
db.generateCode(outputDir, extensionsDir)
|
||||
|
||||
if doSqueeze:
|
||||
db.squeezeGeneratedCode(outputDir)
|
||||
db.squeezeGeneratedCode(outputDir, deleteSourceAfterSqueeze)
|
||||
|
@ -733,7 +733,7 @@ class FFIInterrogateDatabase:
|
||||
file = open(init, 'w')
|
||||
file.close()
|
||||
|
||||
def squeezeGeneratedCode(self, outputDir):
|
||||
def squeezeGeneratedCode(self, outputDir, deleteSource=True):
|
||||
|
||||
# Since we will be squeezing the importModuleName file, rename
|
||||
# the original to something we can import from within the
|
||||
@ -762,9 +762,10 @@ class FFIInterrogateDatabase:
|
||||
pandaSqueezeTool.squeeze(squeezedName, unsqueezedName,
|
||||
files, outputDir)
|
||||
|
||||
# Remove the now-squeezed source files.
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
if( deleteSource ):
|
||||
# Remove the now-squeezed source files.
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
|
||||
|
||||
def generateCodeLib(self, codeDir, extensionsDir, CModuleName):
|
||||
|
@ -39,7 +39,7 @@
|
||||
// All of the Sources.pp files in the current source hierarchy
|
||||
// $DTOOL/pptempl/Global.pp
|
||||
// $DTOOL/pptempl/Global.nmake.pp
|
||||
// $DTOOL/pptempl/Depends.pp, once for each Sources.pp filem
|
||||
// $DTOOL/pptempl/Depends.pp, once for each Sources.pp file
|
||||
// Template.nmake.pp (this file), once for each Sources.pp file
|
||||
|
||||
#if $[ne $[CTPROJS],]
|
||||
@ -106,6 +106,14 @@
|
||||
#define lxx_st_sources $[sort $[lxx_sources(metalib_target lib_target noinst_lib_target static_lib_target ss_lib_target bin_target noinst_bin_target test_bin_target test_lib_target)]]
|
||||
#define dep_sources_1 $[sort $[get_sources(metalib_target lib_target noinst_lib_target static_lib_target ss_lib_target bin_target noinst_bin_target test_bin_target test_lib_target)]]
|
||||
|
||||
// If there is an __init__.py in the directory, then all Python
|
||||
// files in the directory just get installed without having to be
|
||||
// named.
|
||||
#if $[and $[INSTALL_PYTHON_SOURCE],$[wildcard $[TOPDIR]/$[DIRPREFIX]__init__.py]]
|
||||
#define py_sources $[wildcard $[TOPDIR]/$[DIRPREFIX]*.py]
|
||||
#endif
|
||||
#define install_py $[py_sources:$[TOPDIR]/$[DIRPREFIX]%=%]
|
||||
|
||||
// These are the source files that our dependency cache file will
|
||||
// depend on. If it's an empty list, we won't bother writing rules to
|
||||
// freshen the cache file.
|
||||
@ -171,6 +179,7 @@
|
||||
$[if $[install_data],$[install_data_dir]] \
|
||||
$[if $[install_config],$[install_config_dir]] \
|
||||
$[if $[install_igatedb],$[install_igatedb_dir]] \
|
||||
$[if $[install_py],$[install_py_dir] $[install_py_package_dir]] \
|
||||
]
|
||||
|
||||
// Similarly, we need to ensure that $[ODIR] exists. Trying to make
|
||||
@ -285,7 +294,8 @@ $[TAB] if exist $[file] del /f $[file]
|
||||
$[INSTALL_HEADERS:%=$[install_headers_dir]/%] \
|
||||
$[INSTALL_PARSER_INC:%=$[install_parser_inc_dir]/%] \
|
||||
$[INSTALL_DATA:%=$[install_data_dir]/%] \
|
||||
$[INSTALL_CONFIG:%=$[install_config_dir]/%]
|
||||
$[INSTALL_CONFIG:%=$[install_config_dir]/%] \
|
||||
$[if $[install_py],$[install_py:%=$[install_py_dir]/%] $[install_py_package_dir]/__init__.py]
|
||||
|
||||
#define installed_igate_files \
|
||||
$[get_igatedb(metalib_target lib_target ss_lib_target):$[ODIR]/%=$[install_igatedb_dir]/%]
|
||||
@ -923,6 +933,18 @@ $[osfilename $[install_config_dir]/$[file]] : $[patsubst %,$[osfilename %],$[fil
|
||||
$[TAB] xcopy /I/Y $[osfilename $[local]] $[osfilename $[dest]]
|
||||
#end file
|
||||
|
||||
#foreach file $[install_py]
|
||||
$[osfilename $[install_py_dir]/$[file]] : $[patsubst %,$[osfilename %],$[file]]
|
||||
#define local $[file]
|
||||
#define dest $[install_py_dir]
|
||||
$[TAB] xcopy /I/Y $[osfilename $[local]] $[osfilename $[dest]]
|
||||
#end file
|
||||
|
||||
#if $[install_py]
|
||||
$[osfilename $[install_py_package_dir]/__init__.py] :
|
||||
$[TAB] echo. > $[osfilename $[install_py_package_dir]/__init__.py]
|
||||
#endif
|
||||
|
||||
// Finally, all the special targets. These are commands that just need
|
||||
// to be invoked; we don't pretend to know what they are.
|
||||
#forscopes special_target
|
||||
|
@ -66,6 +66,17 @@ FmodAudioManager() {
|
||||
_cache_limit = audio_cache_limit;
|
||||
_concurrent_sound_limit = 0;
|
||||
|
||||
// RobCode
|
||||
// Fill list of supported types
|
||||
// Order of this list (first is most important) determines
|
||||
// the search order for sound files without an extension.
|
||||
_supported_types.push_back("wav");
|
||||
_supported_types.push_back("ogg");
|
||||
_supported_types.push_back("mp3");
|
||||
_supported_types.push_back("mid");
|
||||
_supported_types.push_back("midi");
|
||||
_supported_types.push_back("rmi");
|
||||
|
||||
// Initialize FMOD, if this is the first manager created.
|
||||
_is_valid = true;
|
||||
if (_active_managers == 0) {
|
||||
@ -168,11 +179,55 @@ get_sound(const string &file_name, bool positional) {
|
||||
nassertr(is_valid(), NULL);
|
||||
Filename path = file_name;
|
||||
|
||||
if (use_vfs) {
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
vfs->resolve_filename(path, get_sound_path());
|
||||
} else {
|
||||
path.resolve_filename(get_sound_path());
|
||||
// RobCode
|
||||
// test for an invalid suffix type
|
||||
string suffix = downcase(path.get_extension());
|
||||
if (!suffix.empty()) {
|
||||
SupportedTypes::iterator type_i=find(_supported_types.begin(), _supported_types.end(), suffix);
|
||||
// if suffix not found in list of supported types
|
||||
if (type_i == _supported_types.end()) {
|
||||
// print error and return
|
||||
audio_error("FmodAudioManager::get_sound: \""<<path<<"\" is not a supported sound file format.");
|
||||
audio_error("Supported formats are: WAV, OGG, MP3, MID, MIDI, RMI");
|
||||
return get_null_sound();
|
||||
} else { // the suffix is of a supported type
|
||||
audio_debug("FmodAudioManager::get_sound: \""<<path<<"\" is a supported sound file format.");
|
||||
// resolve the path normally
|
||||
if (use_vfs) {
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
vfs->resolve_filename(path, get_sound_path());
|
||||
} else {
|
||||
path.resolve_filename(get_sound_path());
|
||||
}
|
||||
}
|
||||
} else { // no suffix given. Search for supported file types of the same name.
|
||||
audio_debug("FmodAudioManager::get_sound: \""<<path<<"\" has no extension. Searching for supported files with the same name.");
|
||||
// look for each type of file
|
||||
SupportedTypes::const_iterator type_i;
|
||||
for (type_i = _supported_types.begin(); type_i != _supported_types.end(); ++type_i) {
|
||||
path.set_extension(*type_i); // set extension as supported type
|
||||
|
||||
if (use_vfs) { // check virtual file system
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
if (vfs->resolve_filename(path, get_sound_path())) {
|
||||
break; // break out of loop with a valid type_i value and path with correct extension
|
||||
}
|
||||
} else { // check regular file system
|
||||
if (path.resolve_filename(get_sound_path())) {
|
||||
break; // break out of loop with a valid type_i value and path with correct extension
|
||||
}
|
||||
}
|
||||
} // end for loop
|
||||
// if no valid file found
|
||||
if (type_i == _supported_types.end() ) {
|
||||
// just print a warning for now
|
||||
audio_debug("FmodAudioManager::get_sound: \""<<file_name<<"\" does not exist, even with default sound extensions.");
|
||||
// reset path to no extension
|
||||
path.set_extension("");
|
||||
} else {
|
||||
audio_debug("FmodAudioManager::get_sound: \""<<path<<"\" found using default sound extensions.");
|
||||
suffix = downcase(path.get_extension()); // update suffix (used below when loading file)
|
||||
}
|
||||
}
|
||||
|
||||
audio_debug(" resolved file_name is '"<<path<<"'");
|
||||
@ -241,7 +296,7 @@ get_sound(const string &file_name, bool positional) {
|
||||
}
|
||||
|
||||
string os_path = path.to_os_specific();
|
||||
string suffix = downcase(path.get_extension());
|
||||
//string suffix = downcase(path.get_extension()); // declared above by RobCode
|
||||
|
||||
if (suffix == "mid" || suffix == "rmi" || suffix == "midi") {
|
||||
stream = FSOUND_Stream_Open(os_path.c_str(), 0, 0, 0);
|
||||
|
@ -136,6 +136,11 @@ private:
|
||||
typedef pdeque<string> LRU;
|
||||
LRU _lru;
|
||||
|
||||
// RobCode
|
||||
// List of supported sound formats
|
||||
typedef pvector<string> SupportedTypes;
|
||||
SupportedTypes _supported_types;
|
||||
|
||||
void release_sound(FmodAudioSound *audioSound);
|
||||
|
||||
int _cache_limit;
|
||||
|
@ -92,6 +92,23 @@ get_ascii_equivalent() const {
|
||||
return has_ascii_equivalent() ? (char)_index : '\0';
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonHandle::matches
|
||||
// Access: Published
|
||||
// Description: Returns true if this ButtonHandle is the same as the
|
||||
// other one, or if the other one is an alias for this
|
||||
// one. (Does not return true if this button is an
|
||||
// alias for the other one, however.)
|
||||
//
|
||||
// This is a more general comparison than operator ==.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ButtonHandle::
|
||||
matches(const ButtonHandle &other) const {
|
||||
return ((*this) == other ||
|
||||
(other != ButtonHandle::none() &&
|
||||
get_alias() == other));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonHandle::get_index
|
||||
// Access: Published
|
||||
|
@ -36,3 +36,25 @@ get_name() const {
|
||||
return ButtonRegistry::ptr()->get_name(*this);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonHandle::get_alias
|
||||
// Access: Published
|
||||
// Description: Returns the alias (alternate name) associated with
|
||||
// the button, if any, or ButtonHandle::none() if the
|
||||
// button has no alias.
|
||||
//
|
||||
// Each button is allowed to have one alias, and
|
||||
// multiple different buttons can refer to the same
|
||||
// alias. The alias should be the more general name for
|
||||
// the button, for instance, shift is an alias for
|
||||
// lshift, but not vice-versa.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ButtonHandle ButtonHandle::
|
||||
get_alias() const {
|
||||
if ((*this) == ButtonHandle::none()) {
|
||||
return ButtonHandle::none();
|
||||
} else {
|
||||
return ButtonRegistry::ptr()->get_alias(*this);
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,10 @@ PUBLISHED:
|
||||
INLINE bool has_ascii_equivalent() const;
|
||||
INLINE char get_ascii_equivalent() const;
|
||||
|
||||
ButtonHandle get_alias() const;
|
||||
|
||||
INLINE bool matches(const ButtonHandle &other) const;
|
||||
|
||||
INLINE int get_index() const;
|
||||
INLINE void output(ostream &out) const;
|
||||
INLINE static ButtonHandle none();
|
||||
|
@ -24,13 +24,14 @@
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ButtonRegistry::RegistryNode::
|
||||
RegistryNode(ButtonHandle handle, const string &name) :
|
||||
_handle(handle), _name(name) {
|
||||
RegistryNode(ButtonHandle handle, ButtonHandle alias, const string &name) :
|
||||
_handle(handle), _alias(alias), _name(name)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonRegistry::ptr
|
||||
// Access: Public, Static
|
||||
// Access: Published, Static
|
||||
// Description: Returns the pointer to the global ButtonRegistry
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -53,3 +54,17 @@ get_name(ButtonHandle button) const {
|
||||
nassertr(rnode != (RegistryNode *)NULL, "");
|
||||
return rnode->_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonRegistry::get_alias
|
||||
// Access: Public
|
||||
// Description: Returns the alias for the indicated button, or
|
||||
// ButtonHandle::none() if the button has no specified
|
||||
// alias.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ButtonHandle ButtonRegistry::
|
||||
get_alias(ButtonHandle button) const {
|
||||
RegistryNode *rnode = look_up(button);
|
||||
nassertr(rnode != (RegistryNode *)NULL, ButtonHandle::none());
|
||||
return rnode->_alias;
|
||||
}
|
||||
|
@ -38,13 +38,21 @@ ButtonRegistry *ButtonRegistry::_global_pointer = NULL;
|
||||
// it was already registered; in either case, the new
|
||||
// ButtonHandle is loaded into the first parameter.
|
||||
//
|
||||
// If the alias is not ButtonHandle::none(), it
|
||||
// indicates an alias (alternate name) for the same
|
||||
// button. Each button is allowed to have one alias,
|
||||
// and multiple different buttons can refer to the same
|
||||
// alias. The alias should be the more general name for
|
||||
// the button, for instance, shift is an alias for
|
||||
// lshift, but not vice-versa.
|
||||
//
|
||||
// This defines a new kind of button matching the
|
||||
// indicated name. The ButtonHandle can then be passed
|
||||
// around to devices as a button in its own right.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ButtonRegistry::
|
||||
register_button(ButtonHandle &button_handle, const string &name,
|
||||
char ascii_equivalent) {
|
||||
ButtonHandle alias, char ascii_equivalent) {
|
||||
NameRegistry::iterator ri;
|
||||
ri = _name_registry.find(name);
|
||||
|
||||
@ -81,7 +89,7 @@ register_button(ButtonHandle &button_handle, const string &name,
|
||||
ButtonHandle new_handle;
|
||||
new_handle._index = index;
|
||||
|
||||
RegistryNode *rnode = new RegistryNode(new_handle, name);
|
||||
RegistryNode *rnode = new RegistryNode(new_handle, alias, name);
|
||||
_handle_registry[index] = rnode;
|
||||
_name_registry[name] = rnode;
|
||||
|
||||
@ -108,7 +116,7 @@ register_button(ButtonHandle &button_handle, const string &name,
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonRegistry::get_button
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Finds a ButtonHandle in the registry matching the
|
||||
// indicated name. If there is no such ButtonHandle,
|
||||
// registers a new one and returns it.
|
||||
@ -129,7 +137,7 @@ get_button(const string &name) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonRegistry::find_ascii_button
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Finds a ButtonHandle in the registry matching the
|
||||
// indicated ASCII equivalent character. If there is no
|
||||
// such ButtonHandle, returns ButtonHandle::none().
|
||||
@ -142,10 +150,9 @@ find_ascii_button(char ascii_equivalent) const {
|
||||
return _handle_registry[ascii_equivalent]->_handle;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonRegistry::write
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ButtonRegistry::
|
||||
@ -165,11 +172,16 @@ write(ostream &out) const {
|
||||
NameRegistry::const_iterator ri;
|
||||
for (ri = _name_registry.begin(); ri != _name_registry.end(); ++ri) {
|
||||
if (!(*ri).second->_handle.has_ascii_equivalent()) {
|
||||
out << " " << (*ri).second->_name << "\n";
|
||||
out << " " << (*ri).second->_name;
|
||||
if ((*ri).second->_alias != ButtonHandle::none()) {
|
||||
out << " (alias " << (*ri).second->_alias << ")";
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ButtonRegistry::Constructor
|
||||
// Access: Private
|
||||
|
@ -37,27 +37,31 @@ class EXPCL_PANDA ButtonRegistry {
|
||||
protected:
|
||||
class EXPCL_PANDA RegistryNode {
|
||||
public:
|
||||
INLINE RegistryNode(ButtonHandle handle, const string &name);
|
||||
INLINE RegistryNode(ButtonHandle handle, ButtonHandle alias,
|
||||
const string &name);
|
||||
|
||||
ButtonHandle _handle;
|
||||
ButtonHandle _alias;
|
||||
string _name;
|
||||
};
|
||||
|
||||
public:
|
||||
bool register_button(ButtonHandle &button_handle, const string &name,
|
||||
ButtonHandle alias = ButtonHandle::none(),
|
||||
char ascii_equivalent = '\0');
|
||||
|
||||
PUBLISHED:
|
||||
ButtonHandle get_button(const string &name);
|
||||
ButtonHandle find_ascii_button(char ascii_equivalent) const;
|
||||
|
||||
void write(ostream &out) const;
|
||||
|
||||
// ptr() returns the pointer to the global ButtonRegistry object.
|
||||
INLINE static ButtonRegistry *ptr();
|
||||
|
||||
public:
|
||||
INLINE string get_name(ButtonHandle button) const;
|
||||
|
||||
void write(ostream &out) const;
|
||||
INLINE ButtonHandle get_alias(ButtonHandle button) const;
|
||||
|
||||
private:
|
||||
// The ButtonRegistry class should never be constructed by user code.
|
||||
|
@ -91,6 +91,12 @@ DEFINE_KEYBD_BUTTON_HANDLE(print_screen)
|
||||
DEFINE_KEYBD_BUTTON_HANDLE(shift)
|
||||
DEFINE_KEYBD_BUTTON_HANDLE(control)
|
||||
DEFINE_KEYBD_BUTTON_HANDLE(alt)
|
||||
DEFINE_KEYBD_BUTTON_HANDLE(lshift)
|
||||
DEFINE_KEYBD_BUTTON_HANDLE(rshift)
|
||||
DEFINE_KEYBD_BUTTON_HANDLE(lcontrol)
|
||||
DEFINE_KEYBD_BUTTON_HANDLE(rcontrol)
|
||||
DEFINE_KEYBD_BUTTON_HANDLE(lalt)
|
||||
DEFINE_KEYBD_BUTTON_HANDLE(ralt)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -101,12 +107,18 @@ DEFINE_KEYBD_BUTTON_HANDLE(alt)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void KeyboardButton::
|
||||
init_keyboard_buttons() {
|
||||
ButtonRegistry::ptr()->register_button(_space, "space", ' ');
|
||||
ButtonRegistry::ptr()->register_button(_backspace, "backspace", '\x08');
|
||||
ButtonRegistry::ptr()->register_button(_tab, "tab", '\x09');
|
||||
ButtonRegistry::ptr()->register_button(_enter, "enter", '\x0d');
|
||||
ButtonRegistry::ptr()->register_button(_escape, "escape", '\x1b');
|
||||
ButtonRegistry::ptr()->register_button(_del, "delete", '\x7f');
|
||||
ButtonRegistry::ptr()->register_button(_space, "space",
|
||||
ButtonHandle::none(), ' ');
|
||||
ButtonRegistry::ptr()->register_button(_backspace, "backspace",
|
||||
ButtonHandle::none(), '\x08');
|
||||
ButtonRegistry::ptr()->register_button(_tab, "tab",
|
||||
ButtonHandle::none(), '\x09');
|
||||
ButtonRegistry::ptr()->register_button(_enter, "enter",
|
||||
ButtonHandle::none(), '\x0d');
|
||||
ButtonRegistry::ptr()->register_button(_escape, "escape",
|
||||
ButtonHandle::none(), '\x1b');
|
||||
ButtonRegistry::ptr()->register_button(_del, "delete",
|
||||
ButtonHandle::none(), '\x7f');
|
||||
|
||||
ButtonRegistry::ptr()->register_button(_f1, "f1");
|
||||
ButtonRegistry::ptr()->register_button(_f2, "f2");
|
||||
@ -141,11 +153,19 @@ init_keyboard_buttons() {
|
||||
ButtonRegistry::ptr()->register_button(_scroll_lock, "scroll_lock");
|
||||
ButtonRegistry::ptr()->register_button(_print_screen, "print_screen");
|
||||
|
||||
ButtonRegistry::ptr()->register_button(_lshift, "lshift", _shift);
|
||||
ButtonRegistry::ptr()->register_button(_rshift, "rshift", _shift);
|
||||
ButtonRegistry::ptr()->register_button(_lcontrol, "lcontrol", _control);
|
||||
ButtonRegistry::ptr()->register_button(_rcontrol, "rcontrol", _control);
|
||||
ButtonRegistry::ptr()->register_button(_lalt, "lalt", _alt);
|
||||
ButtonRegistry::ptr()->register_button(_ralt, "ralt", _alt);
|
||||
|
||||
// Also register all of the visible ASCII characters.
|
||||
for (int i = 32; i < 127; i++) {
|
||||
if (isgraph(i)) {
|
||||
ButtonHandle key;
|
||||
ButtonRegistry::ptr()->register_button(key, string(1, (char)i), i);
|
||||
ButtonRegistry::ptr()->register_button(key, string(1, (char)i),
|
||||
ButtonHandle::none(), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,6 +74,13 @@ PUBLISHED:
|
||||
static ButtonHandle scroll_lock();
|
||||
static ButtonHandle print_screen();
|
||||
|
||||
static ButtonHandle lshift();
|
||||
static ButtonHandle rshift();
|
||||
static ButtonHandle lcontrol();
|
||||
static ButtonHandle rcontrol();
|
||||
static ButtonHandle lalt();
|
||||
static ButtonHandle ralt();
|
||||
|
||||
public:
|
||||
static void init_keyboard_buttons();
|
||||
};
|
||||
|
@ -235,7 +235,7 @@ bool ModifierButtons::
|
||||
has_button(ButtonHandle button) const {
|
||||
PTA(ButtonHandle)::const_iterator bi;
|
||||
for (bi = _button_list.begin(); bi != _button_list.end(); ++bi) {
|
||||
if (button == (*bi)) {
|
||||
if (button.matches(*bi)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -250,6 +250,10 @@ has_button(ButtonHandle button) const {
|
||||
// being monitored. Returns true if the button was
|
||||
// removed, false if it was not being monitored in the
|
||||
// first place.
|
||||
//
|
||||
// Unlike the other methods, you cannot remove a button
|
||||
// by removing its alias; you have to remove exactly the
|
||||
// button itself.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ModifierButtons::
|
||||
remove_button(ButtonHandle button) {
|
||||
@ -289,7 +293,7 @@ remove_button(ButtonHandle button) {
|
||||
bool ModifierButtons::
|
||||
button_down(ButtonHandle button) {
|
||||
for (int i = 0; i < (int)_button_list.size(); i++) {
|
||||
if (button == _button_list[i]) {
|
||||
if (button.matches(_button_list[i])) {
|
||||
_state |= ((BitmaskType)1 << i);
|
||||
return true;
|
||||
}
|
||||
@ -311,7 +315,7 @@ button_down(ButtonHandle button) {
|
||||
bool ModifierButtons::
|
||||
button_up(ButtonHandle button) {
|
||||
for (int i = 0; i < (int)_button_list.size(); i++) {
|
||||
if (button == _button_list[i]) {
|
||||
if (button.matches(_button_list[i])) {
|
||||
_state &= ~((BitmaskType)1 << i);
|
||||
return true;
|
||||
}
|
||||
@ -330,7 +334,7 @@ button_up(ButtonHandle button) {
|
||||
bool ModifierButtons::
|
||||
is_down(ButtonHandle button) const {
|
||||
for (int i = 0; i < (int)_button_list.size(); i++) {
|
||||
if (button == _button_list[i]) {
|
||||
if (button.matches(_button_list[i])) {
|
||||
return ((_state & ((BitmaskType)1 << i)) != 0);
|
||||
}
|
||||
}
|
||||
|
@ -93,6 +93,12 @@ WinGraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
|
||||
_cursor = 0;
|
||||
memset(_keyboard_state, 0, sizeof(BYTE) * num_virtual_keys);
|
||||
_lost_keypresses = false;
|
||||
_lshift_down = false;
|
||||
_rshift_down = false;
|
||||
_lcontrol_down = false;
|
||||
_rcontrol_down = false;
|
||||
_lalt_down = false;
|
||||
_ralt_down = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1406,6 +1412,27 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
ScreenToClient(hwnd, &point);
|
||||
handle_keypress(lookup_key(wparam), point.x, point.y,
|
||||
get_message_time());
|
||||
|
||||
// wparam does not contain left/right information for SHIFT,
|
||||
// CONTROL, or ALT, so we have to track their status and do
|
||||
// the right thing. We'll send the left/right specific key
|
||||
// event along with the general key event.
|
||||
//
|
||||
// Key repeating is not being handled consistently for LALT
|
||||
// and RALT, but from comments below, it's only being handled
|
||||
// the way it is for backspace, so we'll leave it as is.
|
||||
if (wparam == VK_MENU) {
|
||||
if ((GetKeyState(VK_LMENU) & 0x8000) != 0 && ! _lalt_down) {
|
||||
handle_keypress(KeyboardButton::lalt(), point.x, point.y,
|
||||
get_message_time());
|
||||
_lalt_down = true;
|
||||
}
|
||||
if ((GetKeyState(VK_RMENU) & 0x8000) != 0 && ! _ralt_down) {
|
||||
handle_keypress(KeyboardButton::ralt(), point.x, point.y,
|
||||
get_message_time());
|
||||
_ralt_down = true;
|
||||
}
|
||||
}
|
||||
if (wparam == VK_F10) {
|
||||
// bypass default windproc F10 behavior (it activates the main
|
||||
// menu, but we have none)
|
||||
@ -1447,6 +1474,34 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
handle_keypress(lookup_key(wparam), point.x, point.y,
|
||||
get_message_time());
|
||||
|
||||
// wparam does not contain left/right information for SHIFT,
|
||||
// CONTROL, or ALT, so we have to track their status and do
|
||||
// the right thing. We'll send the left/right specific key
|
||||
// event along with the general key event.
|
||||
if (wparam == VK_SHIFT) {
|
||||
if ((GetKeyState(VK_LSHIFT) & 0x8000) != 0 && ! _lshift_down) {
|
||||
handle_keypress(KeyboardButton::lshift(), point.x, point.y,
|
||||
get_message_time());
|
||||
_lshift_down = true;
|
||||
}
|
||||
if ((GetKeyState(VK_RSHIFT) & 0x8000) != 0 && ! _rshift_down) {
|
||||
handle_keypress(KeyboardButton::rshift(), point.x, point.y,
|
||||
get_message_time());
|
||||
_rshift_down = true;
|
||||
}
|
||||
} else if(wparam == VK_CONTROL) {
|
||||
if ((GetKeyState(VK_LCONTROL) & 0x8000) != 0 && ! _lcontrol_down) {
|
||||
handle_keypress(KeyboardButton::lcontrol(), point.x, point.y,
|
||||
get_message_time());
|
||||
_lcontrol_down = true;
|
||||
}
|
||||
if ((GetKeyState(VK_RCONTROL) & 0x8000) != 0 && ! _rcontrol_down) {
|
||||
handle_keypress(KeyboardButton::rcontrol(), point.x, point.y,
|
||||
get_message_time());
|
||||
_rcontrol_down = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Cntrl-V paste from clipboard. Is there a better way
|
||||
// to detect this hotkey?
|
||||
if ((wparam=='V') && (GetKeyState(VK_CONTROL) < 0) &&
|
||||
@ -1471,7 +1526,6 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
CloseClipboard();
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Actually, for now we'll respect the repeat anyway, just
|
||||
// so we support backspace properly. Rethink later.
|
||||
@ -1480,6 +1534,58 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
ScreenToClient(hwnd, &point);
|
||||
handle_keypress(lookup_key(wparam), point.x, point.y,
|
||||
get_message_time());
|
||||
|
||||
// wparam does not contain left/right information for SHIFT,
|
||||
// CONTROL, or ALT, so we have to track their status and do
|
||||
// the right thing. We'll send the left/right specific key
|
||||
// event along with the general key event.
|
||||
//
|
||||
// If the user presses LSHIFT and then RSHIFT, the RSHIFT event
|
||||
// will come in with the keyrepeat flag on (i.e. it will end up
|
||||
// in this block). The logic below should detect this correctly
|
||||
// and only send the RSHIFT event. Note that the CONTROL event
|
||||
// will be sent twice, once for each keypress. Since keyrepeats
|
||||
// are currently being sent simply as additional keypress events,
|
||||
// that should be okay for now.
|
||||
if (wparam == VK_SHIFT) {
|
||||
if (((GetKeyState(VK_LSHIFT) & 0x8000) != 0) && ! _lshift_down ) {
|
||||
handle_keypress(KeyboardButton::lshift(), point.x, point.y,
|
||||
get_message_time());
|
||||
_lshift_down = true;
|
||||
} else if (((GetKeyState(VK_RSHIFT) & 0x8000) != 0) && ! _rshift_down ) {
|
||||
handle_keypress(KeyboardButton::rshift(), point.x, point.y,
|
||||
get_message_time());
|
||||
_rshift_down = true;
|
||||
} else {
|
||||
if ((GetKeyState(VK_LSHIFT) & 0x8000) != 0) {
|
||||
handle_keypress(KeyboardButton::lshift(), point.x, point.y,
|
||||
get_message_time());
|
||||
}
|
||||
if ((GetKeyState(VK_RSHIFT) & 0x8000) != 0) {
|
||||
handle_keypress(KeyboardButton::rshift(), point.x, point.y,
|
||||
get_message_time());
|
||||
}
|
||||
}
|
||||
} else if(wparam == VK_CONTROL) {
|
||||
if (((GetKeyState(VK_LCONTROL) & 0x8000) != 0) && ! _lcontrol_down ) {
|
||||
handle_keypress(KeyboardButton::lcontrol(), point.x, point.y,
|
||||
get_message_time());
|
||||
_lcontrol_down = true;
|
||||
} else if (((GetKeyState(VK_RCONTROL) & 0x8000) != 0) && ! _rcontrol_down ) {
|
||||
handle_keypress(KeyboardButton::rcontrol(), point.x, point.y,
|
||||
get_message_time());
|
||||
_rcontrol_down = true;
|
||||
} else {
|
||||
if ((GetKeyState(VK_LCONTROL) & 0x8000) != 0) {
|
||||
handle_keypress(KeyboardButton::lcontrol(), point.x, point.y,
|
||||
get_message_time());
|
||||
}
|
||||
if ((GetKeyState(VK_RCONTROL) & 0x8000) != 0) {
|
||||
handle_keypress(KeyboardButton::rcontrol(), point.x, point.y,
|
||||
get_message_time());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1493,6 +1599,39 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
<< "keyup: " << wparam << " (" << lookup_key(wparam) << ")\n";
|
||||
}
|
||||
handle_keyrelease(lookup_key(wparam), get_message_time());
|
||||
|
||||
// wparam does not contain left/right information for SHIFT,
|
||||
// CONTROL, or ALT, so we have to track their status and do
|
||||
// the right thing. We'll send the left/right specific key
|
||||
// event along with the general key event.
|
||||
if (wparam == VK_SHIFT) {
|
||||
if ((GetKeyState(VK_LSHIFT) & 0x8000) == 0 && _lshift_down) {
|
||||
handle_keyrelease(KeyboardButton::lshift(), get_message_time());
|
||||
_lshift_down = false;
|
||||
}
|
||||
if ((GetKeyState(VK_RSHIFT) & 0x8000) == 0 && _rshift_down) {
|
||||
handle_keyrelease(KeyboardButton::rshift(), get_message_time());
|
||||
_rshift_down = false;
|
||||
}
|
||||
} else if(wparam == VK_CONTROL) {
|
||||
if ((GetKeyState(VK_LCONTROL) & 0x8000) == 0 && _lcontrol_down) {
|
||||
handle_keyrelease(KeyboardButton::lcontrol(), get_message_time());
|
||||
_lcontrol_down = false;
|
||||
}
|
||||
if ((GetKeyState(VK_RCONTROL) & 0x8000) == 0 && _rcontrol_down) {
|
||||
handle_keyrelease(KeyboardButton::rcontrol(), get_message_time());
|
||||
_rcontrol_down = false;
|
||||
}
|
||||
} else if(wparam == VK_MENU) {
|
||||
if ((GetKeyState(VK_LMENU) & 0x8000) == 0 && _lalt_down) {
|
||||
handle_keyrelease(KeyboardButton::lalt(), get_message_time());
|
||||
_lalt_down = false;
|
||||
}
|
||||
if ((GetKeyState(VK_RMENU) & 0x8000) == 0 && _ralt_down) {
|
||||
handle_keyrelease(KeyboardButton::ralt(), get_message_time());
|
||||
_ralt_down = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
@ -1870,20 +2009,17 @@ lookup_key(WPARAM wparam) const {
|
||||
case VK_SCROLL: return KeyboardButton::scroll_lock();
|
||||
case VK_SNAPSHOT: return KeyboardButton::print_screen();
|
||||
|
||||
case VK_SHIFT:
|
||||
case VK_LSHIFT:
|
||||
case VK_RSHIFT:
|
||||
return KeyboardButton::shift();
|
||||
case VK_SHIFT: return KeyboardButton::shift();
|
||||
case VK_LSHIFT: return KeyboardButton::lshift();
|
||||
case VK_RSHIFT: return KeyboardButton::rshift();
|
||||
|
||||
case VK_CONTROL:
|
||||
case VK_LCONTROL:
|
||||
case VK_RCONTROL:
|
||||
return KeyboardButton::control();
|
||||
case VK_CONTROL: return KeyboardButton::control();
|
||||
case VK_LCONTROL: return KeyboardButton::lcontrol();
|
||||
case VK_RCONTROL: return KeyboardButton::rcontrol();
|
||||
|
||||
case VK_MENU:
|
||||
case VK_LMENU:
|
||||
case VK_RMENU:
|
||||
return KeyboardButton::alt();
|
||||
case VK_MENU: return KeyboardButton::alt();
|
||||
case VK_LMENU: return KeyboardButton::lalt();
|
||||
case VK_RMENU: return KeyboardButton::ralt();
|
||||
|
||||
default:
|
||||
int key = MapVirtualKey(wparam, 2);
|
||||
|
@ -139,6 +139,18 @@ private:
|
||||
BYTE _keyboard_state[num_virtual_keys];
|
||||
bool _lost_keypresses;
|
||||
|
||||
// These are used to store the status of the individual left and right
|
||||
// shift, control, and alt keys. Keyboard events are not sent for
|
||||
// these individual keys, but for each pair as a whole. The status
|
||||
// of each key must be checked as keypress and keyrelease events are
|
||||
// received.
|
||||
bool _lshift_down;
|
||||
bool _rshift_down;
|
||||
bool _lcontrol_down;
|
||||
bool _rcontrol_down;
|
||||
bool _lalt_down;
|
||||
bool _ralt_down;
|
||||
|
||||
private:
|
||||
// We need this map to support per-window calls to window_proc().
|
||||
typedef map<HWND, WinGraphicsWindow *> WindowHandles;
|
||||
|
Loading…
x
Reference in New Issue
Block a user