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
|
-r remove the default library list; instrument only named libraries
|
||||||
-O no C++ comments or assertion statements
|
-O no C++ comments or assertion statements
|
||||||
-n Don't use squeezeTool to squeeze the result into one .pyz file
|
-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
|
Any additional names listed on the command line are taken to be names
|
||||||
of libraries that are to be instrumented.
|
of libraries that are to be instrumented.
|
||||||
@ -50,7 +51,8 @@ extensionsDir = ''
|
|||||||
interrogateLib = ''
|
interrogateLib = ''
|
||||||
codeLibs = []
|
codeLibs = []
|
||||||
etcPath = []
|
etcPath = []
|
||||||
doSqueeze = 1
|
doSqueeze = True
|
||||||
|
deleteSourceAfterSqueeze = True
|
||||||
|
|
||||||
def doGetopts():
|
def doGetopts():
|
||||||
global outputDir
|
global outputDir
|
||||||
@ -58,6 +60,7 @@ def doGetopts():
|
|||||||
global interrogateLib
|
global interrogateLib
|
||||||
global codeLibs
|
global codeLibs
|
||||||
global doSqueeze
|
global doSqueeze
|
||||||
|
global deleteSourceAfterSqueeze
|
||||||
global etcPath
|
global etcPath
|
||||||
|
|
||||||
# These options are allowed but are flagged as warnings (they are
|
# These options are allowed but are flagged as warnings (they are
|
||||||
@ -73,7 +76,7 @@ def doGetopts():
|
|||||||
|
|
||||||
# Extract the args the user passed in
|
# Extract the args the user passed in
|
||||||
try:
|
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:
|
except Exception, e:
|
||||||
# User passed in a bad option, print the error and the help, then exit
|
# User passed in a bad option, print the error and the help, then exit
|
||||||
print e
|
print e
|
||||||
@ -105,7 +108,9 @@ def doGetopts():
|
|||||||
FFIConstants.wantComments = 0
|
FFIConstants.wantComments = 0
|
||||||
FFIConstants.wantTypeChecking = 0
|
FFIConstants.wantTypeChecking = 0
|
||||||
elif (flag == '-n'):
|
elif (flag == '-n'):
|
||||||
doSqueeze = 0
|
doSqueeze = False
|
||||||
|
elif (flag == '-s'):
|
||||||
|
deleteSourceAfterSqueeze = False
|
||||||
elif (flag in ['-g', '-t', '-p', '-o']):
|
elif (flag in ['-g', '-t', '-p', '-o']):
|
||||||
FFIConstants.notify.warning("option is deprecated: %s" % (flag))
|
FFIConstants.notify.warning("option is deprecated: %s" % (flag))
|
||||||
|
|
||||||
@ -191,4 +196,4 @@ def run():
|
|||||||
db.generateCode(outputDir, extensionsDir)
|
db.generateCode(outputDir, extensionsDir)
|
||||||
|
|
||||||
if doSqueeze:
|
if doSqueeze:
|
||||||
db.squeezeGeneratedCode(outputDir)
|
db.squeezeGeneratedCode(outputDir, deleteSourceAfterSqueeze)
|
||||||
|
@ -733,7 +733,7 @@ class FFIInterrogateDatabase:
|
|||||||
file = open(init, 'w')
|
file = open(init, 'w')
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
def squeezeGeneratedCode(self, outputDir):
|
def squeezeGeneratedCode(self, outputDir, deleteSource=True):
|
||||||
|
|
||||||
# Since we will be squeezing the importModuleName file, rename
|
# Since we will be squeezing the importModuleName file, rename
|
||||||
# the original to something we can import from within the
|
# the original to something we can import from within the
|
||||||
@ -762,6 +762,7 @@ class FFIInterrogateDatabase:
|
|||||||
pandaSqueezeTool.squeeze(squeezedName, unsqueezedName,
|
pandaSqueezeTool.squeeze(squeezedName, unsqueezedName,
|
||||||
files, outputDir)
|
files, outputDir)
|
||||||
|
|
||||||
|
if( deleteSource ):
|
||||||
# Remove the now-squeezed source files.
|
# Remove the now-squeezed source files.
|
||||||
for file in files:
|
for file in files:
|
||||||
os.remove(file)
|
os.remove(file)
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
// All of the Sources.pp files in the current source hierarchy
|
// All of the Sources.pp files in the current source hierarchy
|
||||||
// $DTOOL/pptempl/Global.pp
|
// $DTOOL/pptempl/Global.pp
|
||||||
// $DTOOL/pptempl/Global.nmake.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
|
// Template.nmake.pp (this file), once for each Sources.pp file
|
||||||
|
|
||||||
#if $[ne $[CTPROJS],]
|
#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 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)]]
|
#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
|
// 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
|
// depend on. If it's an empty list, we won't bother writing rules to
|
||||||
// freshen the cache file.
|
// freshen the cache file.
|
||||||
@ -171,6 +179,7 @@
|
|||||||
$[if $[install_data],$[install_data_dir]] \
|
$[if $[install_data],$[install_data_dir]] \
|
||||||
$[if $[install_config],$[install_config_dir]] \
|
$[if $[install_config],$[install_config_dir]] \
|
||||||
$[if $[install_igatedb],$[install_igatedb_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
|
// 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_HEADERS:%=$[install_headers_dir]/%] \
|
||||||
$[INSTALL_PARSER_INC:%=$[install_parser_inc_dir]/%] \
|
$[INSTALL_PARSER_INC:%=$[install_parser_inc_dir]/%] \
|
||||||
$[INSTALL_DATA:%=$[install_data_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 \
|
#define installed_igate_files \
|
||||||
$[get_igatedb(metalib_target lib_target ss_lib_target):$[ODIR]/%=$[install_igatedb_dir]/%]
|
$[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]]
|
$[TAB] xcopy /I/Y $[osfilename $[local]] $[osfilename $[dest]]
|
||||||
#end file
|
#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
|
// Finally, all the special targets. These are commands that just need
|
||||||
// to be invoked; we don't pretend to know what they are.
|
// to be invoked; we don't pretend to know what they are.
|
||||||
#forscopes special_target
|
#forscopes special_target
|
||||||
|
@ -66,6 +66,17 @@ FmodAudioManager() {
|
|||||||
_cache_limit = audio_cache_limit;
|
_cache_limit = audio_cache_limit;
|
||||||
_concurrent_sound_limit = 0;
|
_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.
|
// Initialize FMOD, if this is the first manager created.
|
||||||
_is_valid = true;
|
_is_valid = true;
|
||||||
if (_active_managers == 0) {
|
if (_active_managers == 0) {
|
||||||
@ -168,12 +179,56 @@ get_sound(const string &file_name, bool positional) {
|
|||||||
nassertr(is_valid(), NULL);
|
nassertr(is_valid(), NULL);
|
||||||
Filename path = file_name;
|
Filename path = file_name;
|
||||||
|
|
||||||
|
// 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) {
|
if (use_vfs) {
|
||||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||||
vfs->resolve_filename(path, get_sound_path());
|
vfs->resolve_filename(path, get_sound_path());
|
||||||
} else {
|
} else {
|
||||||
path.resolve_filename(get_sound_path());
|
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<<"'");
|
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 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") {
|
if (suffix == "mid" || suffix == "rmi" || suffix == "midi") {
|
||||||
stream = FSOUND_Stream_Open(os_path.c_str(), 0, 0, 0);
|
stream = FSOUND_Stream_Open(os_path.c_str(), 0, 0, 0);
|
||||||
|
@ -136,6 +136,11 @@ private:
|
|||||||
typedef pdeque<string> LRU;
|
typedef pdeque<string> LRU;
|
||||||
LRU _lru;
|
LRU _lru;
|
||||||
|
|
||||||
|
// RobCode
|
||||||
|
// List of supported sound formats
|
||||||
|
typedef pvector<string> SupportedTypes;
|
||||||
|
SupportedTypes _supported_types;
|
||||||
|
|
||||||
void release_sound(FmodAudioSound *audioSound);
|
void release_sound(FmodAudioSound *audioSound);
|
||||||
|
|
||||||
int _cache_limit;
|
int _cache_limit;
|
||||||
|
@ -92,6 +92,23 @@ get_ascii_equivalent() const {
|
|||||||
return has_ascii_equivalent() ? (char)_index : '\0';
|
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
|
// Function: ButtonHandle::get_index
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -36,3 +36,25 @@ get_name() const {
|
|||||||
return ButtonRegistry::ptr()->get_name(*this);
|
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 bool has_ascii_equivalent() const;
|
||||||
INLINE char get_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 int get_index() const;
|
||||||
INLINE void output(ostream &out) const;
|
INLINE void output(ostream &out) const;
|
||||||
INLINE static ButtonHandle none();
|
INLINE static ButtonHandle none();
|
||||||
|
@ -24,13 +24,14 @@
|
|||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE ButtonRegistry::RegistryNode::
|
INLINE ButtonRegistry::RegistryNode::
|
||||||
RegistryNode(ButtonHandle handle, const string &name) :
|
RegistryNode(ButtonHandle handle, ButtonHandle alias, const string &name) :
|
||||||
_handle(handle), _name(name) {
|
_handle(handle), _alias(alias), _name(name)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: ButtonRegistry::ptr
|
// Function: ButtonRegistry::ptr
|
||||||
// Access: Public, Static
|
// Access: Published, Static
|
||||||
// Description: Returns the pointer to the global ButtonRegistry
|
// Description: Returns the pointer to the global ButtonRegistry
|
||||||
// object.
|
// object.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -53,3 +54,17 @@ get_name(ButtonHandle button) const {
|
|||||||
nassertr(rnode != (RegistryNode *)NULL, "");
|
nassertr(rnode != (RegistryNode *)NULL, "");
|
||||||
return rnode->_name;
|
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
|
// it was already registered; in either case, the new
|
||||||
// ButtonHandle is loaded into the first parameter.
|
// 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
|
// This defines a new kind of button matching the
|
||||||
// indicated name. The ButtonHandle can then be passed
|
// indicated name. The ButtonHandle can then be passed
|
||||||
// around to devices as a button in its own right.
|
// around to devices as a button in its own right.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool ButtonRegistry::
|
bool ButtonRegistry::
|
||||||
register_button(ButtonHandle &button_handle, const string &name,
|
register_button(ButtonHandle &button_handle, const string &name,
|
||||||
char ascii_equivalent) {
|
ButtonHandle alias, char ascii_equivalent) {
|
||||||
NameRegistry::iterator ri;
|
NameRegistry::iterator ri;
|
||||||
ri = _name_registry.find(name);
|
ri = _name_registry.find(name);
|
||||||
|
|
||||||
@ -81,7 +89,7 @@ register_button(ButtonHandle &button_handle, const string &name,
|
|||||||
ButtonHandle new_handle;
|
ButtonHandle new_handle;
|
||||||
new_handle._index = index;
|
new_handle._index = index;
|
||||||
|
|
||||||
RegistryNode *rnode = new RegistryNode(new_handle, name);
|
RegistryNode *rnode = new RegistryNode(new_handle, alias, name);
|
||||||
_handle_registry[index] = rnode;
|
_handle_registry[index] = rnode;
|
||||||
_name_registry[name] = rnode;
|
_name_registry[name] = rnode;
|
||||||
|
|
||||||
@ -108,7 +116,7 @@ register_button(ButtonHandle &button_handle, const string &name,
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: ButtonRegistry::get_button
|
// Function: ButtonRegistry::get_button
|
||||||
// Access: Public
|
// Access: Published
|
||||||
// Description: Finds a ButtonHandle in the registry matching the
|
// Description: Finds a ButtonHandle in the registry matching the
|
||||||
// indicated name. If there is no such ButtonHandle,
|
// indicated name. If there is no such ButtonHandle,
|
||||||
// registers a new one and returns it.
|
// registers a new one and returns it.
|
||||||
@ -129,7 +137,7 @@ get_button(const string &name) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: ButtonRegistry::find_ascii_button
|
// Function: ButtonRegistry::find_ascii_button
|
||||||
// Access: Public
|
// Access: Published
|
||||||
// Description: Finds a ButtonHandle in the registry matching the
|
// Description: Finds a ButtonHandle in the registry matching the
|
||||||
// indicated ASCII equivalent character. If there is no
|
// indicated ASCII equivalent character. If there is no
|
||||||
// such ButtonHandle, returns ButtonHandle::none().
|
// such ButtonHandle, returns ButtonHandle::none().
|
||||||
@ -142,10 +150,9 @@ find_ascii_button(char ascii_equivalent) const {
|
|||||||
return _handle_registry[ascii_equivalent]->_handle;
|
return _handle_registry[ascii_equivalent]->_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: ButtonRegistry::write
|
// Function: ButtonRegistry::write
|
||||||
// Access: Public
|
// Access: Published
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void ButtonRegistry::
|
void ButtonRegistry::
|
||||||
@ -165,11 +172,16 @@ write(ostream &out) const {
|
|||||||
NameRegistry::const_iterator ri;
|
NameRegistry::const_iterator ri;
|
||||||
for (ri = _name_registry.begin(); ri != _name_registry.end(); ++ri) {
|
for (ri = _name_registry.begin(); ri != _name_registry.end(); ++ri) {
|
||||||
if (!(*ri).second->_handle.has_ascii_equivalent()) {
|
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
|
// Function: ButtonRegistry::Constructor
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -37,27 +37,31 @@ class EXPCL_PANDA ButtonRegistry {
|
|||||||
protected:
|
protected:
|
||||||
class EXPCL_PANDA RegistryNode {
|
class EXPCL_PANDA RegistryNode {
|
||||||
public:
|
public:
|
||||||
INLINE RegistryNode(ButtonHandle handle, const string &name);
|
INLINE RegistryNode(ButtonHandle handle, ButtonHandle alias,
|
||||||
|
const string &name);
|
||||||
|
|
||||||
ButtonHandle _handle;
|
ButtonHandle _handle;
|
||||||
|
ButtonHandle _alias;
|
||||||
string _name;
|
string _name;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool register_button(ButtonHandle &button_handle, const string &name,
|
bool register_button(ButtonHandle &button_handle, const string &name,
|
||||||
|
ButtonHandle alias = ButtonHandle::none(),
|
||||||
char ascii_equivalent = '\0');
|
char ascii_equivalent = '\0');
|
||||||
|
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
ButtonHandle get_button(const string &name);
|
ButtonHandle get_button(const string &name);
|
||||||
ButtonHandle find_ascii_button(char ascii_equivalent) const;
|
ButtonHandle find_ascii_button(char ascii_equivalent) const;
|
||||||
|
|
||||||
|
void write(ostream &out) const;
|
||||||
|
|
||||||
// ptr() returns the pointer to the global ButtonRegistry object.
|
// ptr() returns the pointer to the global ButtonRegistry object.
|
||||||
INLINE static ButtonRegistry *ptr();
|
INLINE static ButtonRegistry *ptr();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
INLINE string get_name(ButtonHandle button) const;
|
INLINE string get_name(ButtonHandle button) const;
|
||||||
|
INLINE ButtonHandle get_alias(ButtonHandle button) const;
|
||||||
void write(ostream &out) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The ButtonRegistry class should never be constructed by user code.
|
// 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(shift)
|
||||||
DEFINE_KEYBD_BUTTON_HANDLE(control)
|
DEFINE_KEYBD_BUTTON_HANDLE(control)
|
||||||
DEFINE_KEYBD_BUTTON_HANDLE(alt)
|
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::
|
void KeyboardButton::
|
||||||
init_keyboard_buttons() {
|
init_keyboard_buttons() {
|
||||||
ButtonRegistry::ptr()->register_button(_space, "space", ' ');
|
ButtonRegistry::ptr()->register_button(_space, "space",
|
||||||
ButtonRegistry::ptr()->register_button(_backspace, "backspace", '\x08');
|
ButtonHandle::none(), ' ');
|
||||||
ButtonRegistry::ptr()->register_button(_tab, "tab", '\x09');
|
ButtonRegistry::ptr()->register_button(_backspace, "backspace",
|
||||||
ButtonRegistry::ptr()->register_button(_enter, "enter", '\x0d');
|
ButtonHandle::none(), '\x08');
|
||||||
ButtonRegistry::ptr()->register_button(_escape, "escape", '\x1b');
|
ButtonRegistry::ptr()->register_button(_tab, "tab",
|
||||||
ButtonRegistry::ptr()->register_button(_del, "delete", '\x7f');
|
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(_f1, "f1");
|
||||||
ButtonRegistry::ptr()->register_button(_f2, "f2");
|
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(_scroll_lock, "scroll_lock");
|
||||||
ButtonRegistry::ptr()->register_button(_print_screen, "print_screen");
|
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.
|
// Also register all of the visible ASCII characters.
|
||||||
for (int i = 32; i < 127; i++) {
|
for (int i = 32; i < 127; i++) {
|
||||||
if (isgraph(i)) {
|
if (isgraph(i)) {
|
||||||
ButtonHandle key;
|
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 scroll_lock();
|
||||||
static ButtonHandle print_screen();
|
static ButtonHandle print_screen();
|
||||||
|
|
||||||
|
static ButtonHandle lshift();
|
||||||
|
static ButtonHandle rshift();
|
||||||
|
static ButtonHandle lcontrol();
|
||||||
|
static ButtonHandle rcontrol();
|
||||||
|
static ButtonHandle lalt();
|
||||||
|
static ButtonHandle ralt();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void init_keyboard_buttons();
|
static void init_keyboard_buttons();
|
||||||
};
|
};
|
||||||
|
@ -235,7 +235,7 @@ bool ModifierButtons::
|
|||||||
has_button(ButtonHandle button) const {
|
has_button(ButtonHandle button) const {
|
||||||
PTA(ButtonHandle)::const_iterator bi;
|
PTA(ButtonHandle)::const_iterator bi;
|
||||||
for (bi = _button_list.begin(); bi != _button_list.end(); ++bi) {
|
for (bi = _button_list.begin(); bi != _button_list.end(); ++bi) {
|
||||||
if (button == (*bi)) {
|
if (button.matches(*bi)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,6 +250,10 @@ has_button(ButtonHandle button) const {
|
|||||||
// being monitored. Returns true if the button was
|
// being monitored. Returns true if the button was
|
||||||
// removed, false if it was not being monitored in the
|
// removed, false if it was not being monitored in the
|
||||||
// first place.
|
// 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::
|
bool ModifierButtons::
|
||||||
remove_button(ButtonHandle button) {
|
remove_button(ButtonHandle button) {
|
||||||
@ -289,7 +293,7 @@ remove_button(ButtonHandle button) {
|
|||||||
bool ModifierButtons::
|
bool ModifierButtons::
|
||||||
button_down(ButtonHandle button) {
|
button_down(ButtonHandle button) {
|
||||||
for (int i = 0; i < (int)_button_list.size(); i++) {
|
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);
|
_state |= ((BitmaskType)1 << i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -311,7 +315,7 @@ button_down(ButtonHandle button) {
|
|||||||
bool ModifierButtons::
|
bool ModifierButtons::
|
||||||
button_up(ButtonHandle button) {
|
button_up(ButtonHandle button) {
|
||||||
for (int i = 0; i < (int)_button_list.size(); i++) {
|
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);
|
_state &= ~((BitmaskType)1 << i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -330,7 +334,7 @@ button_up(ButtonHandle button) {
|
|||||||
bool ModifierButtons::
|
bool ModifierButtons::
|
||||||
is_down(ButtonHandle button) const {
|
is_down(ButtonHandle button) const {
|
||||||
for (int i = 0; i < (int)_button_list.size(); i++) {
|
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);
|
return ((_state & ((BitmaskType)1 << i)) != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,12 @@ WinGraphicsWindow(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
|
|||||||
_cursor = 0;
|
_cursor = 0;
|
||||||
memset(_keyboard_state, 0, sizeof(BYTE) * num_virtual_keys);
|
memset(_keyboard_state, 0, sizeof(BYTE) * num_virtual_keys);
|
||||||
_lost_keypresses = false;
|
_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);
|
ScreenToClient(hwnd, &point);
|
||||||
handle_keypress(lookup_key(wparam), point.x, point.y,
|
handle_keypress(lookup_key(wparam), point.x, point.y,
|
||||||
get_message_time());
|
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) {
|
if (wparam == VK_F10) {
|
||||||
// bypass default windproc F10 behavior (it activates the main
|
// bypass default windproc F10 behavior (it activates the main
|
||||||
// menu, but we have none)
|
// 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,
|
handle_keypress(lookup_key(wparam), point.x, point.y,
|
||||||
get_message_time());
|
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
|
// Handle Cntrl-V paste from clipboard. Is there a better way
|
||||||
// to detect this hotkey?
|
// to detect this hotkey?
|
||||||
if ((wparam=='V') && (GetKeyState(VK_CONTROL) < 0) &&
|
if ((wparam=='V') && (GetKeyState(VK_CONTROL) < 0) &&
|
||||||
@ -1471,7 +1526,6 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||||||
CloseClipboard();
|
CloseClipboard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Actually, for now we'll respect the repeat anyway, just
|
// Actually, for now we'll respect the repeat anyway, just
|
||||||
// so we support backspace properly. Rethink later.
|
// so we support backspace properly. Rethink later.
|
||||||
@ -1480,6 +1534,58 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||||||
ScreenToClient(hwnd, &point);
|
ScreenToClient(hwnd, &point);
|
||||||
handle_keypress(lookup_key(wparam), point.x, point.y,
|
handle_keypress(lookup_key(wparam), point.x, point.y,
|
||||||
get_message_time());
|
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;
|
break;
|
||||||
|
|
||||||
@ -1493,6 +1599,39 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
|||||||
<< "keyup: " << wparam << " (" << lookup_key(wparam) << ")\n";
|
<< "keyup: " << wparam << " (" << lookup_key(wparam) << ")\n";
|
||||||
}
|
}
|
||||||
handle_keyrelease(lookup_key(wparam), get_message_time());
|
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;
|
break;
|
||||||
|
|
||||||
case WM_KILLFOCUS:
|
case WM_KILLFOCUS:
|
||||||
@ -1870,20 +2009,17 @@ lookup_key(WPARAM wparam) const {
|
|||||||
case VK_SCROLL: return KeyboardButton::scroll_lock();
|
case VK_SCROLL: return KeyboardButton::scroll_lock();
|
||||||
case VK_SNAPSHOT: return KeyboardButton::print_screen();
|
case VK_SNAPSHOT: return KeyboardButton::print_screen();
|
||||||
|
|
||||||
case VK_SHIFT:
|
case VK_SHIFT: return KeyboardButton::shift();
|
||||||
case VK_LSHIFT:
|
case VK_LSHIFT: return KeyboardButton::lshift();
|
||||||
case VK_RSHIFT:
|
case VK_RSHIFT: return KeyboardButton::rshift();
|
||||||
return KeyboardButton::shift();
|
|
||||||
|
|
||||||
case VK_CONTROL:
|
case VK_CONTROL: return KeyboardButton::control();
|
||||||
case VK_LCONTROL:
|
case VK_LCONTROL: return KeyboardButton::lcontrol();
|
||||||
case VK_RCONTROL:
|
case VK_RCONTROL: return KeyboardButton::rcontrol();
|
||||||
return KeyboardButton::control();
|
|
||||||
|
|
||||||
case VK_MENU:
|
case VK_MENU: return KeyboardButton::alt();
|
||||||
case VK_LMENU:
|
case VK_LMENU: return KeyboardButton::lalt();
|
||||||
case VK_RMENU:
|
case VK_RMENU: return KeyboardButton::ralt();
|
||||||
return KeyboardButton::alt();
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
int key = MapVirtualKey(wparam, 2);
|
int key = MapVirtualKey(wparam, 2);
|
||||||
|
@ -139,6 +139,18 @@ private:
|
|||||||
BYTE _keyboard_state[num_virtual_keys];
|
BYTE _keyboard_state[num_virtual_keys];
|
||||||
bool _lost_keypresses;
|
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:
|
private:
|
||||||
// We need this map to support per-window calls to window_proc().
|
// We need this map to support per-window calls to window_proc().
|
||||||
typedef map<HWND, WinGraphicsWindow *> WindowHandles;
|
typedef map<HWND, WinGraphicsWindow *> WindowHandles;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user