Merge branch 'release/1.10.x'

This commit is contained in:
rdb 2020-02-23 14:53:16 +01:00
commit c59b91f503
17 changed files with 187 additions and 91 deletions

View File

@ -396,27 +396,22 @@ class build_apps(setuptools.Command):
self.announce('Gathering wheels for platform: {}'.format(platform), distutils.log.INFO) self.announce('Gathering wheels for platform: {}'.format(platform), distutils.log.INFO)
whldir = os.path.join(self.build_base, '__whl_cache__') whlcache = os.path.join(self.build_base, '__whl_cache__')
#TODO find a better way to get abi tag than from internal/private pip APIs pip_version = int(pip.__version__.split('.')[0])
if hasattr(pip, 'pep425tags'): if pip_version < 9:
pep425tags = pip.pep425tags raise RuntimeError("pip 9.0 or greater is required, but found {}".format(pip.__version__))
wheel = pip.wheel
else:
from pip._internal import pep425tags, wheel
abi_tag = pep425tags.get_abi_tag() abi_tag = 'cp%d%d' % (sys.version_info[:2])
if sys.version_info < (3, 8):
if 'u' in abi_tag and (platform.startswith('win') or platform.startswith('macosx')): abi_tag += 'm'
abi_tag = abi_tag.replace('u', '')
# For these distributions, we need to append 'u' on Linux # For these distributions, we need to append 'u' on Linux
if abi_tag in ('cp26m', 'cp27m', 'cp32m') and not platform.startswith('win') and not platform.startswith('macosx'): if abi_tag in ('cp26m', 'cp27m', 'cp32m') and not platform.startswith('win') and not platform.startswith('macosx'):
abi_tag += 'u' abi_tag += 'u'
pip_version = pip.__version__.split('.') whldir = os.path.join(whlcache, '_'.join((platform, abi_tag)))
if int(pip_version[0]) < 9: os.makedirs(whldir, exist_ok=True)
raise RuntimeError("pip 9.0 or greater is required, but found {}".format(pip.__version__))
# Remove any .zip files. These are built from a VCS and block for an # Remove any .zip files. These are built from a VCS and block for an
# interactive prompt on subsequent downloads. # interactive prompt on subsequent downloads.
@ -444,19 +439,12 @@ class build_apps(setuptools.Command):
subprocess.check_call([sys.executable, '-m', 'pip'] + pip_args) subprocess.check_call([sys.executable, '-m', 'pip'] + pip_args)
# Now figure out which of the downloaded wheels are relevant to us. # Return a list of paths to the downloaded whls
tags = pep425tags.get_supported(platform=platform, abi=abi_tag) return [
wheelpaths = [] os.path.join(whldir, filename)
for filename in os.listdir(whldir): for filename in os.listdir(whldir)
try: if filename.endswith('.whl')
whl = wheel.Wheel(filename) ]
except wheel.InvalidWheelFilename:
continue
if whl.supported(tags):
wheelpaths.append(os.path.join(whldir, filename))
return wheelpaths
def update_pe_resources(self, appname, runtime): def update_pe_resources(self, appname, runtime):
"""Update resources (e.g., icons) in windows PE file""" """Update resources (e.g., icons) in windows PE file"""

View File

@ -22,7 +22,7 @@
#include "executionEnvironment.h" #include "executionEnvironment.h"
#include <windows.h> #include <windows.h>
#include <Tlhelp32.h> #include <tlhelp32.h>
using std::string; using std::string;

View File

@ -1442,7 +1442,7 @@ is_void(CPPType *type) {
/** /**
* Returns true if the indicated type is some class that derives from * Returns true if the indicated type is some class that derives from
* ReferenceCount, or false otherwise. * ReferenceCount, or defines ref and unref(), or false otherwise.
*/ */
bool TypeManager:: bool TypeManager::
is_reference_count(CPPType *type) { is_reference_count(CPPType *type) {
@ -1459,6 +1459,14 @@ is_reference_count(CPPType *type) {
case CPPDeclaration::ST_struct: case CPPDeclaration::ST_struct:
{ {
CPPStructType *stype = type->as_struct_type(); CPPStructType *stype = type->as_struct_type();
// If we have methods named ref() and unref(), this is good enough.
if (stype->_scope->_functions.count("ref") &&
stype->_scope->_functions.count("unref") &&
stype->_scope->_functions.count("get_ref_count")) {
return true;
}
CPPStructType::Derivation::const_iterator di; CPPStructType::Derivation::const_iterator di;
for (di = stype->_derivation.begin(); for (di = stype->_derivation.begin();
di != stype->_derivation.end(); di != stype->_derivation.end();

View File

@ -397,6 +397,20 @@ elif target == 'linux' and (os.path.isfile("/lib/libc-2.5.so") or os.path.isfile
else: else:
PLATFORM = 'manylinux1-i686' PLATFORM = 'manylinux1-i686'
elif target == 'linux' and (os.path.isfile("/lib/libc-2.12.so") or os.path.isfile("/lib64/libc-2.12.so")) and os.path.isdir("/opt/python"):
# Same sloppy check for manylinux2010.
if GetTargetArch() in ('x86_64', 'amd64'):
PLATFORM = 'manylinux2010-x86_64'
else:
PLATFORM = 'manylinux2010-i686'
elif target == 'linux' and (os.path.isfile("/lib/libc-2.17.so") or os.path.isfile("/lib64/libc-2.17.so")) and os.path.isdir("/opt/python"):
# Same sloppy check for manylinux2014.
if GetTargetArch() in ('x86_64', 'amd64'):
PLATFORM = 'manylinux2014-x86_64'
else:
PLATFORM = 'manylinux2014-i686'
elif not CrossCompiling(): elif not CrossCompiling():
if HasTargetArch(): if HasTargetArch():
# Replace the architecture in the platform string. # Replace the architecture in the platform string.

View File

@ -92,7 +92,7 @@ EXCLUDE_EXT = [".pyc", ".pyo", ".N", ".prebuilt", ".xcf", ".plist", ".vcproj", "
# Plug-ins to install. # Plug-ins to install.
PLUGIN_LIBS = ["pandagl", "pandagles", "pandagles2", "pandadx9", "p3tinydisplay", "p3ptloader", "p3assimp", "p3ffmpeg", "p3openal_audio", "p3fmod_audio"] PLUGIN_LIBS = ["pandagl", "pandagles", "pandagles2", "pandadx9", "p3tinydisplay", "p3ptloader", "p3assimp", "p3ffmpeg", "p3openal_audio", "p3fmod_audio"]
# Libraries included in manylinux ABI that should be ignored. See PEP 513/571. # Libraries included in manylinux ABI that should be ignored. See PEP 513/571/599.
MANYLINUX_LIBS = [ MANYLINUX_LIBS = [
"libgcc_s.so.1", "libstdc++.so.6", "libm.so.6", "libdl.so.2", "librt.so.1", "libgcc_s.so.1", "libstdc++.so.6", "libm.so.6", "libdl.so.2", "librt.so.1",
"libcrypt.so.1", "libc.so.6", "libnsl.so.1", "libutil.so.1", "libcrypt.so.1", "libc.so.6", "libnsl.so.1", "libutil.so.1",
@ -530,10 +530,14 @@ def makewheel(version, output_dir, platform=None):
else: else:
print("Could not find platform.dat in build directory") print("Could not find platform.dat in build directory")
platform = get_platform() platform = get_platform()
if platform.startswith("linux-"): if platform.startswith("linux-") and os.path.isdir("/opt/python"):
# Is this manylinux1? # Is this manylinux?
if os.path.isfile("/lib/libc-2.5.so") and os.path.isdir("/opt/python"): if os.path.isfile("/lib/libc-2.5.so") or os.path.isfile("/lib64/libc-2.5.so"):
platform = platform.replace("linux", "manylinux1") platform = platform.replace("linux", "manylinux1")
elif os.path.isfile("/lib/libc-2.12.so") or os.path.isfile("/lib64/libc-2.12.so"):
platform = platform.replace("linux", "manylinux2010")
elif os.path.isfile("/lib/libc-2.17.so") or os.path.isfile("/lib64/libc-2.17.so"):
platform = platform.replace("linux", "manylinux2014")
platform = platform.replace('-', '_').replace('.', '_') platform = platform.replace('-', '_').replace('.', '_')
@ -735,7 +739,12 @@ if __debug__:
pylib_path = os.path.join(get_config_var('LIBDIR'), pylib_name) pylib_path = os.path.join(get_config_var('LIBDIR'), pylib_name)
else: else:
pylib_name = get_config_var('LDLIBRARY') pylib_name = get_config_var('LDLIBRARY')
pylib_path = os.path.join(get_config_var('LIBDIR'), pylib_name) pylib_arch = get_config_var('MULTIARCH')
libdir = get_config_var('LIBDIR')
if pylib_arch and os.path.exists(os.path.join(libdir, pylib_arch, pylib_name)):
pylib_path = os.path.join(libdir, pylib_arch, pylib_name)
else:
pylib_path = os.path.join(libdir, pylib_name)
whl.write_file('deploy_libs/' + pylib_name, pylib_path) whl.write_file('deploy_libs/' + pylib_name, pylib_path)
whl.close() whl.close()

View File

@ -20,7 +20,7 @@
#include "xInputDevice.h" #include "xInputDevice.h"
#include <CfgMgr32.h> #include <cfgmgr32.h>
#include <devpkey.h> #include <devpkey.h>
class WinRawInputDevice; class WinRawInputDevice;

View File

@ -19,7 +19,7 @@
#if defined(_WIN32) && !defined(CPPPARSER) #if defined(_WIN32) && !defined(CPPPARSER)
#include <CfgMgr32.h> #include <cfgmgr32.h>
#include <devpkey.h> #include <devpkey.h>
#include "phidsdi.h" #include "phidsdi.h"

View File

@ -19,8 +19,8 @@
#include "inputDeviceManager.h" #include "inputDeviceManager.h"
#include "string_utils.h" #include "string_utils.h"
#include <XInput.h> #include <xinput.h>
#include <CfgMgr32.h> #include <cfgmgr32.h>
#ifndef XUSER_MAX_COUNT #ifndef XUSER_MAX_COUNT
#define XUSER_MAX_COUNT 4 #define XUSER_MAX_COUNT 4

View File

@ -19,7 +19,7 @@
#if defined(_WIN32) && !defined(CPPPARSER) #if defined(_WIN32) && !defined(CPPPARSER)
#include <CfgMgr32.h> #include <cfgmgr32.h>
class InputDeviceManager; class InputDeviceManager;

View File

@ -56,7 +56,7 @@
#if defined(_WIN32) #if defined(_WIN32)
#define WINDOWS_LEAN_AND_MEAN #define WINDOWS_LEAN_AND_MEAN
#include <WinSock2.h> #include <winsock2.h>
#include <wtypes.h> #include <wtypes.h>
#undef WINDOWS_LEAN_AND_MEAN #undef WINDOWS_LEAN_AND_MEAN
#else #else

View File

@ -19,7 +19,7 @@
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
#ifdef _WIN32 #ifdef _WIN32
#include <WinSock2.h> #include <winsock2.h>
#include <windows.h> // for WSAGetLastError() #include <windows.h> // for WSAGetLastError()
#undef X509_NAME #undef X509_NAME
#endif // _WIN32 #endif // _WIN32

View File

@ -30,7 +30,7 @@
#include "openSSLWrapper.h" #include "openSSLWrapper.h"
#ifdef _WIN32 #ifdef _WIN32
#include <WinSock2.h> #include <winsock2.h>
#include <windows.h> // for select() #include <windows.h> // for select()
#undef X509_NAME #undef X509_NAME
#endif // _WIN32 #endif // _WIN32

View File

@ -53,7 +53,7 @@ typedef unsigned long SOCKET;
************************************************************************/ ************************************************************************/
#elif defined(_WIN32) #elif defined(_WIN32)
#include <winsock2.h> #include <winsock2.h>
#include <Ws2tcpip.h> #include <ws2tcpip.h>
typedef u_short sa_family_t; typedef u_short sa_family_t;

View File

@ -25,7 +25,7 @@
#if defined(CPPPARSER) #if defined(CPPPARSER)
#elif defined(_WIN32) #elif defined(_WIN32)
#include <winsock2.h> // For gethostname() #include <winsock2.h> // For gethostname()
#include <Iphlpapi.h> // For GetAdaptersAddresses() #include <iphlpapi.h> // For GetAdaptersAddresses()
#elif defined(__ANDROID__) #elif defined(__ANDROID__)
#include <net/if.h> #include <net/if.h>
#else #else

View File

@ -223,29 +223,23 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
return false; return false;
} }
GeomVertexDataPipelineReader reader(source_data, current_thread);
reader.check_array_readers();
PStatTimer timer(_munge_sprites_pcollector, current_thread); PStatTimer timer(_munge_sprites_pcollector, current_thread);
_sw_sprites_pcollector.add_level(source_data->get_num_rows()); _sw_sprites_pcollector.add_level(reader.get_num_rows());
GraphicsStateGuardianBase *gsg = traverser->get_gsg(); GraphicsStateGuardianBase *gsg = traverser->get_gsg();
GeomVertexReader vertex(source_data, InternalName::get_vertex(), GeomVertexReader vertex(&reader, InternalName::get_vertex());
current_thread); GeomVertexReader normal(&reader, InternalName::get_normal());
GeomVertexReader normal(source_data, InternalName::get_normal(), GeomVertexReader rotate(&reader, InternalName::get_rotate());
current_thread); GeomVertexReader size(&reader, InternalName::get_size());
GeomVertexReader color(source_data, InternalName::get_color(), GeomVertexReader aspect_ratio(&reader, InternalName::get_aspect_ratio());
current_thread);
GeomVertexReader texcoord(source_data, InternalName::get_texcoord(),
current_thread);
GeomVertexReader rotate(source_data, InternalName::get_rotate(),
current_thread);
GeomVertexReader size(source_data, InternalName::get_size(),
current_thread);
GeomVertexReader aspect_ratio(source_data, InternalName::get_aspect_ratio(),
current_thread);
bool has_normal = (normal.has_column()); bool has_normal = (normal.has_column());
bool has_color = (color.has_column()); bool has_color = (reader.has_column(InternalName::get_color()));
bool has_texcoord = (texcoord.has_column()); bool has_texcoord = (reader.has_column(InternalName::get_texcoord()));
bool has_rotate = (rotate.has_column()); bool has_rotate = (rotate.has_column());
bool has_size = (size.has_column()); bool has_size = (size.has_column());
bool has_aspect_ratio = (aspect_ratio.has_column()); bool has_aspect_ratio = (aspect_ratio.has_column());
@ -280,7 +274,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
{ {
LightMutexHolder holder(_format_lock); LightMutexHolder holder(_format_lock);
SourceFormat sformat(source_data->get_format(), sprite_texcoord); SourceFormat sformat(reader.get_format(), sprite_texcoord);
FormatMap::iterator fmi = _format_map.find(sformat); FormatMap::iterator fmi = _format_map.find(sformat);
if (fmi != _format_map.end()) { if (fmi != _format_map.end()) {
new_format = (*fmi).second; new_format = (*fmi).second;
@ -304,13 +298,13 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
Geom::C_clip_point); Geom::C_clip_point);
} }
if (has_normal) { if (has_normal) {
const GeomVertexColumn *c = normal.get_column(); const GeomVertexColumn *c = reader.get_format()->get_normal_column();
new_array_format->add_column new_array_format->add_column
(InternalName::get_normal(), c->get_num_components(), (InternalName::get_normal(), c->get_num_components(),
c->get_numeric_type(), c->get_contents()); c->get_numeric_type(), c->get_contents());
} }
if (has_color) { if (has_color) {
const GeomVertexColumn *c = color.get_column(); const GeomVertexColumn *c = reader.get_format()->get_color_column();
new_array_format->add_column new_array_format->add_column
(InternalName::get_color(), c->get_num_components(), (InternalName::get_color(), c->get_num_components(),
c->get_numeric_type(), c->get_contents()); c->get_numeric_type(), c->get_contents());
@ -322,12 +316,34 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
Geom::C_texcoord); Geom::C_texcoord);
} else if (has_texcoord) { } else if (has_texcoord) {
const GeomVertexColumn *c = texcoord.get_column(); const GeomVertexColumn *c = reader.get_format()->get_column(InternalName::get_texcoord());
new_array_format->add_column new_array_format->add_column
(InternalName::get_texcoord(), c->get_num_components(), (InternalName::get_texcoord(), c->get_num_components(),
c->get_numeric_type(), c->get_contents()); c->get_numeric_type(), c->get_contents());
} }
// Go through the other columns and copy them from the original.
for (size_t ai = 0; ai < sformat._format->get_num_arrays(); ++ai) {
const GeomVertexArrayFormat *aformat = sformat._format->get_array(ai);
for (size_t ci = 0; ci < aformat->get_num_columns(); ++ci) {
const GeomVertexColumn *column = aformat->get_column(ci);
const InternalName *name = column->get_name();
if (name != InternalName::get_vertex() &&
name != InternalName::get_normal() &&
name != InternalName::get_color() &&
name != InternalName::get_texcoord() &&
name != InternalName::get_rotate() &&
name != InternalName::get_size() &&
name != InternalName::get_aspect_ratio()) {
new_array_format->add_column(name,
column->get_num_components(), column->get_numeric_type(),
column->get_contents());
}
}
}
new_format = GeomVertexFormat::register_format(new_array_format); new_format = GeomVertexFormat::register_format(new_array_format);
_format_map[sformat] = new_format; _format_map[sformat] = new_format;
} }
@ -362,7 +378,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
// Now convert all of the vertices in the GeomVertexData to quads. We // Now convert all of the vertices in the GeomVertexData to quads. We
// always convert all the vertices, assuming all the vertices are referenced // always convert all the vertices, assuming all the vertices are referenced
// by GeomPrimitives, because we want to optimize for the most common case. // by GeomPrimitives, because we want to optimize for the most common case.
int orig_verts = source_data->get_num_rows(); int orig_verts = reader.get_num_rows();
int new_verts = 4 * orig_verts; // each vertex becomes four. int new_verts = 4 * orig_verts; // each vertex becomes four.
PT(GeomVertexData) new_data = new GeomVertexData PT(GeomVertexData) new_data = new GeomVertexData
@ -371,9 +387,50 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
GeomVertexWriter new_vertex(new_data, InternalName::get_vertex()); GeomVertexWriter new_vertex(new_data, InternalName::get_vertex());
GeomVertexWriter new_normal(new_data, InternalName::get_normal()); GeomVertexWriter new_normal(new_data, InternalName::get_normal());
GeomVertexWriter new_color(new_data, InternalName::get_color());
GeomVertexWriter new_texcoord(new_data, InternalName::get_texcoord()); GeomVertexWriter new_texcoord(new_data, InternalName::get_texcoord());
nassertr(new_vertex.has_column(), false);
unsigned char *write_ptr = new_vertex.get_array_handle()->get_write_pointer();
// Collect all other columns that we just need to copy the data of.
struct CopyOp {
unsigned char *_to_pointer;
const unsigned char *_from_pointer;
size_t _num_bytes;
size_t _from_stride;
};
pvector<CopyOp> copies;
const GeomVertexArrayFormat *aformat = new_format->get_array(0);
for (size_t ci = 0; ci < aformat->get_num_columns(); ++ci) {
const GeomVertexColumn *column = aformat->get_column(ci);
const InternalName *name = column->get_name();
if (name != InternalName::get_vertex() &&
(retransform_sprites || name != InternalName::get_normal()) &&
(!sprite_texcoord || name != InternalName::get_texcoord())) {
int source_array;
const GeomVertexColumn *source_column;
if (reader.get_format()->get_array_info(name, source_array, source_column)) {
CopyOp copy;
copy._to_pointer = write_ptr + (size_t)column->get_start();
copy._from_pointer = reader.get_array_reader(source_array)->get_read_pointer(true) + (size_t)source_column->get_start();
copy._num_bytes = (size_t)column->get_total_bytes();
copy._from_stride = reader.get_format()->get_array(source_array)->get_stride();
if (!copies.empty() &&
(copy._to_pointer == copies.back()._to_pointer + copies.back()._num_bytes) &&
(copy._from_pointer == copies.back()._from_pointer + copies.back()._num_bytes)) {
// Merge with previous.
copies.back()._num_bytes += copy._num_bytes;
} else {
copies.push_back(copy);
}
}
}
}
size_t to_stride = aformat->get_stride();
// We'll keep an array of all of the points' eye-space coordinates, and // We'll keep an array of all of the points' eye-space coordinates, and
// their distance from the camera, so we can sort the points for each // their distance from the camera, so we can sort the points for each
// primitive, below. // primitive, below.
@ -447,14 +504,6 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3]))); new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3])));
new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3]))); new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3])));
if (has_normal) {
const LNormal &c = normal.get_data3();
new_normal.set_data3(c);
new_normal.set_data3(c);
new_normal.set_data3(c);
new_normal.set_data3(c);
}
} else { } else {
// Without retransform_sprites, we can simply load the clip-space // Without retransform_sprites, we can simply load the clip-space
// coordinates. // coordinates.
@ -464,6 +513,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
new_vertex.set_data4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3]); new_vertex.set_data4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3]);
if (has_normal) { if (has_normal) {
// We need to transform the normals to clip-space too, then.
LNormal c = render_transform.xform_vec(normal.get_data3()); LNormal c = render_transform.xform_vec(normal.get_data3());
new_normal.set_data3(c); new_normal.set_data3(c);
new_normal.set_data3(c); new_normal.set_data3(c);
@ -471,24 +521,24 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
new_normal.set_data3(c); new_normal.set_data3(c);
} }
} }
if (has_color) {
const LColor &c = color.get_data4();
new_color.set_data4(c);
new_color.set_data4(c);
new_color.set_data4(c);
new_color.set_data4(c);
}
if (sprite_texcoord) { if (sprite_texcoord) {
new_texcoord.set_data2(1.0f, 0.0f); new_texcoord.set_data2(1.0f, 0.0f);
new_texcoord.set_data2(0.0f, 0.0f); new_texcoord.set_data2(0.0f, 0.0f);
new_texcoord.set_data2(1.0f, 1.0f); new_texcoord.set_data2(1.0f, 1.0f);
new_texcoord.set_data2(0.0f, 1.0f); new_texcoord.set_data2(0.0f, 1.0f);
} else if (has_texcoord) { }
const LVecBase4 &c = texcoord.get_data4();
new_texcoord.set_data4(c); // Other columns are simply duplicated for each vertex.
new_texcoord.set_data4(c); for (CopyOp &copy : copies) {
new_texcoord.set_data4(c); memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
new_texcoord.set_data4(c); copy._to_pointer += to_stride;
memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
copy._to_pointer += to_stride;
memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
copy._to_pointer += to_stride;
memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
copy._to_pointer += to_stride;
copy._from_pointer += copy._from_stride;
} }
++vi; ++vi;

View File

@ -28,7 +28,7 @@
#include <algorithm> #include <algorithm>
#ifdef _WIN32 #ifdef _WIN32
#include <Winsock2.h> #include <winsock2.h>
#include <windows.h> #include <windows.h>
#endif #endif

View File

@ -2038,6 +2038,13 @@ get_keyboard_map() const {
LightReMutexHolder holder(x11GraphicsPipe::_x_mutex); LightReMutexHolder holder(x11GraphicsPipe::_x_mutex);
for (int k = 9; k <= 135; ++k) { for (int k = 9; k <= 135; ++k) {
if (k >= 78 && k <= 91) {
// Ignore numpad keys for now. These are not mapped to separate button
// handles in Panda, so we don't want their mappings to conflict with
// the regular numeric keys.
continue;
}
ButtonHandle raw_button = map_raw_button(k); ButtonHandle raw_button = map_raw_button(k);
if (raw_button == ButtonHandle::none()) { if (raw_button == ButtonHandle::none()) {
continue; continue;
@ -2045,11 +2052,31 @@ get_keyboard_map() const {
KeySym sym = XkbKeycodeToKeysym(_display, k, 0, 0); KeySym sym = XkbKeycodeToKeysym(_display, k, 0, 0);
ButtonHandle button = map_button(sym); ButtonHandle button = map_button(sym);
if (button == ButtonHandle::none()) { std::string label;
// Compose a label for some keys; I have not yet been able to find an API
// that does this effectively.
if (sym >= XK_a && sym <= XK_z) {
label = toupper((char)sym);
}
else if (sym >= XK_F1 && sym <= XK_F35) {
label = "F" + format_string(sym - XK_F1 + 1);
}
else if (sym >= XK_exclamdown && sym <= XK_ydiaeresis) {
// A latin-1 symbol. Translate this to the label.
char buffer[255];
int nbytes = XkbTranslateKeySym(_display, &sym, 0, buffer, 255, 0);
if (nbytes > 0) {
label.assign(buffer, nbytes);
}
}
if (button == ButtonHandle::none() && label.empty()) {
// No label and no mapping; this is useless.
continue; continue;
} }
map->map_button(raw_button, button); map->map_button(raw_button, button, label);
} }
return map; return map;