diff --git a/contrib/src/panda3dtoolsgui/Panda3DToolsGUI.py b/contrib/src/panda3dtoolsgui/Panda3DToolsGUI.py index 0c8b3f3ccd..331081016b 100644 --- a/contrib/src/panda3dtoolsgui/Panda3DToolsGUI.py +++ b/contrib/src/panda3dtoolsgui/Panda3DToolsGUI.py @@ -1905,7 +1905,7 @@ class main(wx.Frame): self.txaExtraLines.append(line) txafile.close() except: - print "Error opening .txa file!" + print("Error opening .txa file!") self.palettize_saveTxaTxt.SetValue(os.path.join(dirname + os.sep , filename)) dlg.Destroy() @@ -2705,7 +2705,7 @@ class main(wx.Frame): selectedItemIndex = int(self.batchTree.GetItemText(selectedItemId).split()[0])-1 batchItem = self.batchList[selectedItemIndex] - print '\n'+self.BuildCommand(batchItem) + print('\n'+self.BuildCommand(batchItem)) if (batchItem['cmd'].count('maya2egg')): # Display Maya2Egg Tool Panel @@ -2840,7 +2840,7 @@ class main(wx.Frame): self.txaExtraLines.append(line) txafile.close() except: - print "Error opening .txa file!" + print("Error opening .txa file!") self.batchItemNameTxt.SetValue(batchItem['label']) diff --git a/direct/src/dist/FreezeTool.py b/direct/src/dist/FreezeTool.py index da9d7ecf56..4bf6dca3ac 100644 --- a/direct/src/dist/FreezeTool.py +++ b/direct/src/dist/FreezeTool.py @@ -90,6 +90,7 @@ defaultHiddenImports = { 'scipy.special._ufuncs': ['scipy.special._ufuncs_cxx'], 'scipy.stats._stats': ['scipy.special.cython_special'], 'setuptools.monkey': ['setuptools.msvc'], + 'shapely._geometry_helpers': ['shapely._geos'], } @@ -2583,6 +2584,21 @@ class PandaModuleFinder(modulefinder.ModuleFinder): else: code = fp.read() + # Strip out delvewheel patch (see GitHub issue #1492) + if isinstance(code, bytes): + # Don't look for \n at the end, it may also be \r\n + start_marker = b'# start delvewheel patch' + end_marker = b'# end delvewheel patch' + else: + start_marker = '# start delvewheel patch' + end_marker = '# end delvewheel patch' + + start = code.find(start_marker) + while start >= 0: + end = code.find(end_marker, start) + len(end_marker) + code = code[:start] + code[end:] + start = code.find(start_marker) + code += b'\n' if isinstance(code, bytes) else '\n' co = compile(code, pathname, 'exec', optimize=self.optimize) elif type == imp.PY_COMPILED: diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index 4213db21fa..6036c6abcc 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -634,7 +634,20 @@ class build_apps(setuptools.Command): for index in self.pypi_extra_indexes: pip_args += ['--extra-index-url', index] - subprocess.check_call([sys.executable, '-m', 'pip'] + pip_args) + try: + subprocess.check_call([sys.executable, '-m', 'pip'] + pip_args) + except: + # Display a more helpful message for these common issues. + if platform.startswith('manylinux2010_') and sys.version_info >= (3, 11): + new_platform = platform.replace('manylinux2010_', 'manylinux2014_') + self.announce('This error likely occurs because {} is not a supported target as of Python 3.11.\nChange the target platform to {} instead.'.format(platform, new_platform), distutils.log.ERROR) + elif platform.startswith('manylinux1_') and sys.version_info >= (3, 10): + new_platform = platform.replace('manylinux1_', 'manylinux2014_') + self.announce('This error likely occurs because {} is not a supported target as of Python 3.10.\nChange the target platform to {} instead.'.format(platform, new_platform), distutils.log.ERROR) + elif platform.startswith('macosx_10_6_') and sys.version_info >= (3, 8): + new_platform = platform.replace('macosx_10_6_', 'macosx_10_9_') + self.announce('This error likely occurs because {} is not a supported target as of Python 3.8.\nChange the target platform to {} instead.'.format(platform, new_platform), distutils.log.ERROR) + raise # Return a list of paths to the downloaded whls return [ diff --git a/dtool/src/dtoolutil/filename.cxx b/dtool/src/dtoolutil/filename.cxx index abb21a8ee2..d8dd0a5651 100644 --- a/dtool/src/dtoolutil/filename.cxx +++ b/dtool/src/dtoolutil/filename.cxx @@ -1289,9 +1289,12 @@ to_os_long_name() const { } /** - * Returns true if the filename exists on the disk, false otherwise. If the - * type is indicated to be executable, this also tests that the file has + * Returns true if the filename exists on the physical disk, false otherwise. + * If the type is indicated to be executable, this also tests that the file has * execute permission. + * + * @see VirtualFileSystem::exists() for checking whether the filename exists in + * the virtual file system. */ bool Filename:: exists() const { @@ -1320,8 +1323,11 @@ exists() const { } /** - * Returns true if the filename exists and is the name of a regular file (i.e. - * not a directory or device), false otherwise. + * Returns true if the filename exists on the physical disk and is the name of + * a regular file (i.e. not a directory or device), false otherwise. + * + * @see VirtualFileSystem::is_regular_file() for checking whether the filename + * exists and is a regular file in the virtual file system. */ bool Filename:: is_regular_file() const { @@ -1350,8 +1356,8 @@ is_regular_file() const { } /** - * Returns true if the filename exists and is either a directory or a regular - * file that can be written to, or false otherwise. + * Returns true if the filename exists on the physical disk and is either a + * directory or a regular file that can be written to, or false otherwise. */ bool Filename:: is_writable() const { @@ -1382,8 +1388,11 @@ is_writable() const { } /** - * Returns true if the filename exists and is a directory name, false - * otherwise. + * Returns true if the filename exists on the physical disk and is a directory + * name, false otherwise. + * + * @see VirtualFileSystem::is_directory() for checking whether the filename + * exists as a directory in the virtual file system. */ bool Filename:: is_directory() const { diff --git a/dtool/src/dtoolutil/filename.h b/dtool/src/dtoolutil/filename.h index 94001417db..f28f08753c 100644 --- a/dtool/src/dtoolutil/filename.h +++ b/dtool/src/dtoolutil/filename.h @@ -36,6 +36,11 @@ class DSearchPath; * convention, and it knows how to perform basic OS-specific I/O, like testing * for file existence and searching a searchpath, as well as the best way to * open an fstream for reading or writing. + * + * Note that the methods of Filename that interact with the filesystem (such + * as exists(), open_read(), etc.) directly interface with the operating system + * and are not aware of Panda's virtual file system. To interact with the VFS, + * use the methods on VirtualFileSystem instead. */ class EXPCL_DTOOL_DTOOLUTIL Filename { PUBLISHED: diff --git a/dtool/src/interrogate/functionRemap.cxx b/dtool/src/interrogate/functionRemap.cxx index 725b1f578b..6d6ce0f911 100644 --- a/dtool/src/interrogate/functionRemap.cxx +++ b/dtool/src/interrogate/functionRemap.cxx @@ -494,6 +494,10 @@ get_call_str(const string &container, const vector_string &pexprs) const { call << separator << "self"; separator = ", "; } + if (_flags & F_explicit_cls) { + call << separator << "cls"; + separator = ", "; + } size_t pn; size_t num_parameters = pexprs.size(); @@ -781,14 +785,20 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak first_param = 1; } - if (_parameters.size() > first_param && _parameters[first_param]._name == "self" && + if (_parameters.size() > first_param && TypeManager::is_pointer_to_PyObject(_parameters[first_param]._remap->get_orig_type())) { // Here's a special case. If the first parameter of a nonstatic method // is a PyObject * called "self", then we will automatically fill it in - // from the this pointer, and remove it from the generated parameter - // list. - _parameters.erase(_parameters.begin() + first_param); - _flags |= F_explicit_self; + // from the this pointer, and remove it from the generated parameter list. + // For static methods, we offer "cls" instead, containing the type object. + if (_parameters[first_param]._name == "self") { + _parameters.erase(_parameters.begin() + first_param); + _flags |= F_explicit_self; + } + else if (!_has_this && _parameters[first_param]._name == "cls") { + _parameters.erase(_parameters.begin() + first_param); + _flags |= F_explicit_cls; + } } if (_parameters.size() == first_param) { diff --git a/dtool/src/interrogate/functionRemap.h b/dtool/src/interrogate/functionRemap.h index b2e6615659..f6d2fea30c 100644 --- a/dtool/src/interrogate/functionRemap.h +++ b/dtool/src/interrogate/functionRemap.h @@ -101,6 +101,7 @@ public: F_divide_integer = 0x2000, F_hash = 0x4000, F_explicit_args = 0x8000, + F_explicit_cls =0x10000, }; typedef std::vector Parameters; diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 7c79a717e3..b55026b2da 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -1706,7 +1706,11 @@ write_module_class(ostream &out, Object *obj) { } if (!func->_has_this) { - flags += " | METH_STATIC"; + if (func->_flags & FunctionRemap::F_explicit_cls) { + flags += " | METH_CLASS"; + } else { + flags += " | METH_STATIC"; + } // Skip adding this entry if we also have a property with the same name. // In that case, we will use a Dtool_StaticProperty to disambiguate @@ -3652,6 +3656,9 @@ write_function_for_top(ostream &out, InterfaceMaker::Object *obj, InterfaceMaker if (func->_has_this) { prototype += "self"; } + else if (func->_flags & FunctionRemap::F_explicit_cls) { + prototype += "cls"; + } switch (func->_args_type) { case AT_keyword_args: diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index 6d4e19981e..39b5de5140 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -1150,8 +1150,9 @@ clear_pipe() { /** * Changes the x_size and y_size, then recalculates structures that depend on - * size. The recalculation currently includes: - compute_pixels on all the - * graphics regions. - updating the texture card, if one is present. + * size. The recalculation currently includes: + * - compute_pixels on all the graphics regions. + * - updating the texture card, if one is present. */ void GraphicsOutput:: set_size_and_recalc(int x, int y) { @@ -1163,11 +1164,8 @@ set_size_and_recalc(int x, int y) { int fb_x_size = get_fb_x_size(); int fb_y_size = get_fb_y_size(); - TotalDisplayRegions::iterator dri; - for (dri = _total_display_regions.begin(); - dri != _total_display_regions.end(); - ++dri) { - (*dri)->compute_pixels_all_stages(fb_x_size, fb_y_size); + for (DisplayRegion *dr : _total_display_regions) { + dr->compute_pixels_all_stages(fb_x_size, fb_y_size); } if (_texture_card != nullptr && _texture_card->get_num_geoms() > 0) { diff --git a/panda/src/egldisplay/eglGraphicsBuffer.cxx b/panda/src/egldisplay/eglGraphicsBuffer.cxx index 2cfbff83b4..a71f562611 100644 --- a/panda/src/egldisplay/eglGraphicsBuffer.cxx +++ b/panda/src/egldisplay/eglGraphicsBuffer.cxx @@ -38,9 +38,10 @@ eglGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe, DCAST_INTO_V(egl_pipe, _pipe); _pbuffer = EGL_NO_SURFACE; - // Since the pbuffer never gets flipped, we get screenshots from the same - // buffer we draw into. - _screenshot_buffer_type = _draw_buffer_type; + // EGL pbuffers only have a back buffer (see 2.2.2 in spec), and it is never + // flipped (eglSwapBuffers is a no-op). + _draw_buffer_type = RenderBuffer::T_back; + _screenshot_buffer_type = RenderBuffer::T_back; } /** @@ -119,6 +120,30 @@ end_frame(FrameMode mode, Thread *current_thread) { } } +/** + * + */ +void eglGraphicsBuffer:: +set_size(int x, int y) { + nassertv_always(_gsg != nullptr); + + if (_size.get_x() != x || _size.get_y() != y) { + eglDestroySurface(_egl_display, _pbuffer); + + int attrib_list[] = { + EGL_WIDTH, x, + EGL_HEIGHT, y, + EGL_NONE + }; + + eglGraphicsStateGuardian *eglgsg; + DCAST_INTO_V(eglgsg, _gsg); + _pbuffer = eglCreatePbufferSurface(eglgsg->_egl_display, eglgsg->_fbconfig, attrib_list); + } + + set_size_and_recalc(x, y); +} + /** * Closes the buffer right now. Called from the window thread. */ diff --git a/panda/src/egldisplay/eglGraphicsBuffer.h b/panda/src/egldisplay/eglGraphicsBuffer.h index 68697ef94c..60be353e47 100644 --- a/panda/src/egldisplay/eglGraphicsBuffer.h +++ b/panda/src/egldisplay/eglGraphicsBuffer.h @@ -36,6 +36,8 @@ public: virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); + virtual void set_size(int x, int y); + protected: virtual void close_buffer(); virtual bool open_buffer(); diff --git a/panda/src/egldisplay/eglGraphicsPipe.cxx b/panda/src/egldisplay/eglGraphicsPipe.cxx index c32ea29351..aaa6ae0af7 100644 --- a/panda/src/egldisplay/eglGraphicsPipe.cxx +++ b/panda/src/egldisplay/eglGraphicsPipe.cxx @@ -323,7 +323,6 @@ make_output(const std::string &name, if (retry == 2) { if (((flags&BF_require_parasite)!=0)|| ((flags&BF_require_window)!=0)|| - ((flags&BF_resizeable)!=0)|| ((flags&BF_size_track_host)!=0)) { return nullptr; } diff --git a/panda/src/express/virtualFileSystem.I b/panda/src/express/virtualFileSystem.I index b74b9edbee..713b992147 100644 --- a/panda/src/express/virtualFileSystem.I +++ b/panda/src/express/virtualFileSystem.I @@ -12,7 +12,8 @@ */ /** - * Convenience function; returns true if the named file exists. + * Convenience function; returns true if the named file exists in the virtual + * file system hierarchy. */ INLINE bool VirtualFileSystem:: exists(const Filename &filename) const { @@ -20,8 +21,8 @@ exists(const Filename &filename) const { } /** - * Convenience function; returns true if the named file exists and is a - * directory. + * Convenience function; returns true if the named file exists as a directory in + * the virtual file system hierarchy. */ INLINE bool VirtualFileSystem:: is_directory(const Filename &filename) const { @@ -30,8 +31,8 @@ is_directory(const Filename &filename) const { } /** - * Convenience function; returns true if the named file exists and is a - * regular file. + * Convenience function; returns true if the named file exists as a regular file + * in the virtual file system hierarchy. */ INLINE bool VirtualFileSystem:: is_regular_file(const Filename &filename) const { diff --git a/panda/src/iphone/ipfreeze.py b/panda/src/iphone/ipfreeze.py index d7fe343a15..8762b95b63 100755 --- a/panda/src/iphone/ipfreeze.py +++ b/panda/src/iphone/ipfreeze.py @@ -17,8 +17,8 @@ import os from direct.dist import FreezeTool def usage(code, msg = ''): - print >> sys.stderr, __doc__ - print >> sys.stderr, msg + print(__doc__, file=sys.stderr) + print(msg, file=sys.stderr) sys.exit(code) if __name__ == '__main__': @@ -30,7 +30,7 @@ if __name__ == '__main__': try: opts, args = getopt.getopt(sys.argv[1:], 'h') - except getopt.error, msg: + except getopt.error as msg: usage(1, msg) for opt, arg in opts: diff --git a/panda/src/iphone/provision.py b/panda/src/iphone/provision.py index 47a445d3cc..ffdefc6fa0 100755 --- a/panda/src/iphone/provision.py +++ b/panda/src/iphone/provision.py @@ -34,7 +34,7 @@ command = 'env CODESIGN_ALLOCATE="/Developer/Platforms/iPhoneOS.platform/Develop 'xcent' : xcent, } -print command +print(command) result = os.system(command) if result != 0: raise StandardError diff --git a/panda/src/pgraph/CMakeLists.txt b/panda/src/pgraph/CMakeLists.txt index 8319e31863..cf3f65f22c 100644 --- a/panda/src/pgraph/CMakeLists.txt +++ b/panda/src/pgraph/CMakeLists.txt @@ -204,6 +204,8 @@ set(P3PGRAPH_SOURCES ) set(P3PGRAPH_IGATEEXT + bamFile_ext.cxx + bamFile_ext.h loaderFileTypeRegistry_ext.cxx loaderFileTypeRegistry_ext.h nodePathCollection_ext.cxx diff --git a/panda/src/pgraph/bamFile.h b/panda/src/pgraph/bamFile.h index a244ab3fa3..32793e512e 100644 --- a/panda/src/pgraph/bamFile.h +++ b/panda/src/pgraph/bamFile.h @@ -74,7 +74,11 @@ PUBLISHED: BamReader *get_reader(); BamWriter *get_writer(); +public: + EXTENSION(PyObject *get_file_version() const); + PUBLISHED: + MAKE_PROPERTY(file_version, get_file_version); MAKE_PROPERTY(file_endian, get_file_endian); MAKE_PROPERTY(file_stdfloat_double, get_file_stdfloat_double); diff --git a/panda/src/pgraph/bamFile_ext.cxx b/panda/src/pgraph/bamFile_ext.cxx new file mode 100644 index 0000000000..6c5cd04e1a --- /dev/null +++ b/panda/src/pgraph/bamFile_ext.cxx @@ -0,0 +1,28 @@ +/** + * PANDA 3D SOFTWARE + * Copyright (c) Carnegie Mellon University. All rights reserved. + * + * All use of this software is subject to the terms of the revised BSD + * license. You should have received a copy of this license along + * with this source code in a file named "LICENSE." + * + * @file bamFile_ext.cxx + * @author rdb + * @date 2023-05-03 + */ + +#include "bamFile_ext.h" +#include "bamWriter_ext.h" + +#ifdef HAVE_PYTHON + +/** + * Returns the version number of the Bam file currently being written. + */ +PyObject *Extension:: +get_file_version() const { + return Py_BuildValue("(ii)", _this->get_file_major_ver(), + _this->get_file_minor_ver()); +} + +#endif diff --git a/panda/src/pgraph/bamFile_ext.h b/panda/src/pgraph/bamFile_ext.h new file mode 100644 index 0000000000..7a6408d531 --- /dev/null +++ b/panda/src/pgraph/bamFile_ext.h @@ -0,0 +1,37 @@ +/** + * PANDA 3D SOFTWARE + * Copyright (c) Carnegie Mellon University. All rights reserved. + * + * All use of this software is subject to the terms of the revised BSD + * license. You should have received a copy of this license along + * with this source code in a file named "LICENSE." + * + * @file bamFile_ext.h + * @author rdb + * @date 2023-05-03 + */ + +#ifndef BAMFILE_EXT_H +#define BAMFILE_EXT_H + +#include "dtoolbase.h" + +#ifdef HAVE_PYTHON + +#include "extension.h" +#include "bamFile.h" +#include "py_panda.h" + +/** + * This class defines the extension methods for BamFile, which are called + * instead of any C++ methods with the same prototype. + */ +template<> +class Extension : public ExtensionBase { +public: + PyObject *get_file_version() const; +}; + +#endif // HAVE_PYTHON + +#endif // BAMFILE_EXT_H diff --git a/panda/src/pgraph/p3pgraph_ext_composite.cxx b/panda/src/pgraph/p3pgraph_ext_composite.cxx index 37b9012c76..493636ccda 100644 --- a/panda/src/pgraph/p3pgraph_ext_composite.cxx +++ b/panda/src/pgraph/p3pgraph_ext_composite.cxx @@ -1,3 +1,4 @@ +#include "bamFile_ext.cxx" #include "loaderFileTypeRegistry_ext.cxx" #include "nodePath_ext.cxx" #include "nodePathCollection_ext.cxx" diff --git a/panda/src/putil/CMakeLists.txt b/panda/src/putil/CMakeLists.txt index d935d59c33..6f63c5d490 100644 --- a/panda/src/putil/CMakeLists.txt +++ b/panda/src/putil/CMakeLists.txt @@ -125,6 +125,8 @@ set(P3PUTIL_SOURCES set(P3PUTIL_IGATEEXT bamReader_ext.cxx bamReader_ext.h + bamWriter_ext.cxx + bamWriter_ext.h bitArray_ext.cxx bitArray_ext.h bitArray_ext.I diff --git a/panda/src/putil/bamReader.cxx b/panda/src/putil/bamReader.cxx index 75b2f65b19..6bed7b8ad6 100644 --- a/panda/src/putil/bamReader.cxx +++ b/panda/src/putil/bamReader.cxx @@ -315,7 +315,7 @@ read_object(TypedWritable *&ptr, ReferenceCount *&ref_ptr) { * time to call it. * * This must be called at least once after reading a particular object via - * get_object() in order to validate that object. + * read_object() in order to validate that object. * * The return value is true if all objects have been resolved, or false if * some objects are still outstanding (in which case you will need to call diff --git a/panda/src/putil/bamWriter.h b/panda/src/putil/bamWriter.h index 780104b61c..be07d80411 100644 --- a/panda/src/putil/bamWriter.h +++ b/panda/src/putil/bamWriter.h @@ -87,9 +87,13 @@ PUBLISHED: INLINE TypedWritable *get_root_node() const; INLINE void set_root_node(TypedWritable *root_node); +public: + EXTENSION(PyObject *get_file_version() const); + PUBLISHED: MAKE_PROPERTY(target, get_target, set_target); MAKE_PROPERTY(filename, get_filename); + MAKE_PROPERTY(file_version, get_file_version); MAKE_PROPERTY(file_endian, get_file_endian); MAKE_PROPERTY(file_stdfloat_double, get_file_stdfloat_double); MAKE_PROPERTY(file_texture_mode, get_file_texture_mode); diff --git a/panda/src/putil/bamWriter_ext.cxx b/panda/src/putil/bamWriter_ext.cxx new file mode 100644 index 0000000000..ea5b451eb6 --- /dev/null +++ b/panda/src/putil/bamWriter_ext.cxx @@ -0,0 +1,28 @@ +/** + * PANDA 3D SOFTWARE + * Copyright (c) Carnegie Mellon University. All rights reserved. + * + * All use of this software is subject to the terms of the revised BSD + * license. You should have received a copy of this license along + * with this source code in a file named "LICENSE." + * + * @file bamWriter_ext.cxx + * @author rdb + * @date 2023-05-03 + */ + +#include "bamWriter_ext.h" +#include "config_putil.h" + +#ifdef HAVE_PYTHON + +/** + * Returns the version number of the Bam file currently being written. + */ +PyObject *Extension:: +get_file_version() const { + return Py_BuildValue("(ii)", _this->get_file_major_ver(), + _this->get_file_minor_ver()); +} + +#endif diff --git a/panda/src/putil/bamWriter_ext.h b/panda/src/putil/bamWriter_ext.h new file mode 100644 index 0000000000..1f0b3eefb1 --- /dev/null +++ b/panda/src/putil/bamWriter_ext.h @@ -0,0 +1,37 @@ +/** + * PANDA 3D SOFTWARE + * Copyright (c) Carnegie Mellon University. All rights reserved. + * + * All use of this software is subject to the terms of the revised BSD + * license. You should have received a copy of this license along + * with this source code in a file named "LICENSE." + * + * @file bamWriter_ext.h + * @author rdb + * @date 2023-05-01 + */ + +#ifndef BAMWRITER_EXT_H +#define BAMWRITER_EXT_H + +#include "dtoolbase.h" + +#ifdef HAVE_PYTHON + +#include "extension.h" +#include "bamWriter.h" +#include "py_panda.h" + +/** + * This class defines the extension methods for BamWriter, which are called + * instead of any C++ methods with the same prototype. + */ +template<> +class Extension : public ExtensionBase { +public: + PyObject *get_file_version() const; +}; + +#endif // HAVE_PYTHON + +#endif // BAMWRITER_EXT_H diff --git a/panda/src/putil/datagramOutputFile.cxx b/panda/src/putil/datagramOutputFile.cxx index 407e1adfec..6d285a7f3e 100644 --- a/panda/src/putil/datagramOutputFile.cxx +++ b/panda/src/putil/datagramOutputFile.cxx @@ -86,6 +86,22 @@ close() { _error = false; } +/** + * Writes a sequence of bytes to the beginning of the datagram file. This may + * be called any number of times after the file has been opened and before the + * first datagram is written. It may not be called once the first datagram is + * written. + */ +bool DatagramOutputFile:: +write_header(const vector_uchar &header) { + nassertr(_out != nullptr, false); + nassertr(!_wrote_first_datagram, false); + + _out->write((const char *)&header[0], header.size()); + thread_consider_yield(); + return !_out->fail(); +} + /** * Writes a sequence of bytes to the beginning of the datagram file. This may * be called any number of times after the file has been opened and before the diff --git a/panda/src/putil/datagramOutputFile.h b/panda/src/putil/datagramOutputFile.h index 17402850b0..fbc88e0bcd 100644 --- a/panda/src/putil/datagramOutputFile.h +++ b/panda/src/putil/datagramOutputFile.h @@ -38,6 +38,7 @@ PUBLISHED: void close(); + bool write_header(const vector_uchar &header); bool write_header(const std::string &header); virtual bool put_datagram(const Datagram &data); virtual bool copy_datagram(SubfileInfo &result, const Filename &filename); diff --git a/panda/src/putil/p3putil_ext_composite.cxx b/panda/src/putil/p3putil_ext_composite.cxx index 6306661a7f..abb9df3b73 100644 --- a/panda/src/putil/p3putil_ext_composite.cxx +++ b/panda/src/putil/p3putil_ext_composite.cxx @@ -1,4 +1,5 @@ #include "bamReader_ext.cxx" +#include "bamWriter_ext.cxx" #include "bitArray_ext.cxx" #include "paramPyObject.cxx" #include "pythonCallbackObject.cxx" diff --git a/panda/src/testbed/test_native_net1.py b/panda/src/testbed/test_native_net1.py index 0e4738e8ad..dd96973b16 100644 --- a/panda/src/testbed/test_native_net1.py +++ b/panda/src/testbed/test_native_net1.py @@ -11,7 +11,7 @@ SocketIP.InitNetworkDriver(); addr = SocketAddress() addr.setHost("127.0.0.1",8080) -print addr.getIpPort() +print(addr.getIpPort()) inbound = SocketTCPListen() @@ -23,16 +23,16 @@ while 1 == 1: source = SocketAddress() if inbound.GetIncomingConnection(newsession,source) : #newsession.SetNonBlocking(); - print source.getIpPort() + print(source.getIpPort()) newsession.SendData("Hello From the Listener\n\r"); s = newsession.RecvData(10); - print s - print newsession.GetLastError() + print(s) + print(newsession.GetLastError()) if newsession.ErrorIsWouldBlocking(newsession.GetLastError()) : - print "Reading Would Block" + print("Reading Would Block") else: - print "Not A Blocking Error" + print("Not A Blocking Error") newsession.SendData("GoodBy From the Listener\n\r"); newsession.Close(); diff --git a/panda/src/testbed/test_native_net2.py b/panda/src/testbed/test_native_net2.py index 44c197911b..002b223f53 100644 --- a/panda/src/testbed/test_native_net2.py +++ b/panda/src/testbed/test_native_net2.py @@ -15,7 +15,7 @@ SocketIP.InitNetworkDriver(); addr = SocketAddress() addr.setHost("127.0.0.1",6666) -print addr.getIpPort() +print(addr.getIpPort()) MyConection = BufferedDatagramConnection(0,4096000,4096000,102400); #help(BufferedDatagramConnection) @@ -42,8 +42,8 @@ dg1.addUint16(54321) while 1==1: for x in range(200000): if not MyConection.SendMessage(dg1): - print "Error Sending Message" + print("Error Sending Message") MyConection.Flush(); time.sleep(1) - print "loop" + print("loop") diff --git a/panda/src/testbed/test_native_net3.py b/panda/src/testbed/test_native_net3.py index dff516eb60..d1d9486ee6 100644 --- a/panda/src/testbed/test_native_net3.py +++ b/panda/src/testbed/test_native_net3.py @@ -15,7 +15,7 @@ SocketIP.InitNetworkDriver(); addr = SocketAddress() addr.setHost("127.0.0.1",6666) -print addr.getIpPort() +print(addr.getIpPort()) MyConection = BufferedDatagramConnection(0,4096000,4096000,102400); #help(BufferedDatagramConnection) @@ -47,4 +47,4 @@ while 1==1: MyConection.Flush(); time.sleep(1) - print "loop" + print("loop") diff --git a/panda/src/windisplay/winGraphicsWindow.cxx b/panda/src/windisplay/winGraphicsWindow.cxx index 9b5827a0a1..5aceb2b54b 100644 --- a/panda/src/windisplay/winGraphicsWindow.cxx +++ b/panda/src/windisplay/winGraphicsWindow.cxx @@ -272,15 +272,34 @@ process_events() { */ void WinGraphicsWindow:: set_properties_now(WindowProperties &properties) { - if (properties.has_fullscreen() && !properties.get_fullscreen() && - is_fullscreen()) { - if (do_windowed_switch()) { - _properties.set_fullscreen(false); - properties.clear_fullscreen(); - } else { - windisplay_cat.warning() - << "Switching to windowed mode failed!\n"; + if (properties.has_fullscreen()) { + if (!properties.get_fullscreen() && is_fullscreen()) { + if (do_windowed_switch()) { + _properties.set_fullscreen(false); + } else { + windisplay_cat.warning() + << "Switching to windowed mode failed!\n"; + } } + else if (properties.get_fullscreen() && !is_fullscreen()) { + int x_size; + int y_size; + if (properties.has_size()) { + x_size = properties.get_x_size(); + y_size = properties.get_y_size(); + } else { + x_size = _properties.get_x_size(); + y_size = _properties.get_y_size(); + } + if (do_fullscreen_switch(x_size, y_size)) { + _properties.set_fullscreen(true); + properties.clear_size(); + } else { + windisplay_cat.warning() + << "Switching to fullscreen mode failed!\n"; + } + } + properties.clear_fullscreen(); } GraphicsWindow::set_properties_now(properties); @@ -974,8 +993,8 @@ do_fullscreen_resize(int x_size, int y_size) { * Called in the set_properties_now function to switch to fullscreen. */ bool WinGraphicsWindow:: -do_fullscreen_switch() { - if (!do_fullscreen_enable()) { +do_fullscreen_switch(int x_size, int y_size) { + if (!do_fullscreen_enable(x_size, y_size)) { // Couldn't get fullscreen. return false; } @@ -985,17 +1004,21 @@ do_fullscreen_switch() { DWORD window_style = make_style(props); SetWindowLong(_hWnd, GWL_STYLE, window_style); - WINDOW_METRICS metrics; - bool has_origin; - if (!calculate_metrics(true, window_style, metrics, has_origin)){ - return false; - } - - SetWindowPos(_hWnd, HWND_NOTOPMOST, 0, 0, metrics.width, metrics.height, + SetWindowPos(_hWnd, HWND_NOTOPMOST, 0, 0, x_size, y_size, SWP_FRAMECHANGED | SWP_SHOWWINDOW); + + handle_reshape(); return true; } +/** + * Called in the set_properties_now function to switch to fullscreen. + */ +bool WinGraphicsWindow:: +do_fullscreen_switch() { + return do_fullscreen_switch(_properties.get_x_size(), _properties.get_y_size()); +} + /** * Called in the set_properties_now function to switch to windowed mode. */ @@ -1248,8 +1271,8 @@ open_graphic_window() { // somehow, but I need the window's black background to cover up the desktop // during the mode change. - if (fullscreen){ - if (!do_fullscreen_enable()){ + if (fullscreen) { + if (!do_fullscreen_enable()) { return false; } } @@ -1262,7 +1285,7 @@ open_graphic_window() { * Not to confuse with do_fullscreen_switch(). */ bool WinGraphicsWindow:: -do_fullscreen_enable() { +do_fullscreen_enable(int x_size, int y_size) { HWND hDesktopWindow = GetDesktopWindow(); HDC scrnDC = GetDC(hDesktopWindow); @@ -1272,8 +1295,8 @@ do_fullscreen_enable() { // GetDeviceCaps(scrnDC, VERTRES); ReleaseDC(hDesktopWindow, scrnDC); - DWORD dwWidth = _properties.get_x_size(); - DWORD dwHeight = _properties.get_y_size(); + DWORD dwWidth = x_size; + DWORD dwHeight = y_size; DWORD dwFullScreenBitDepth = cur_bitdepth; DEVMODE dm; @@ -1301,12 +1324,16 @@ do_fullscreen_enable() { } _fullscreen_display_mode = dm; - - _properties.set_origin(0, 0); - _properties.set_size(dwWidth, dwHeight); - return true; +} +/** + * This is a low-level function that just puts Windows in fullscreen mode. + * Not to confuse with do_fullscreen_switch(). + */ +bool WinGraphicsWindow:: +do_fullscreen_enable() { + return do_fullscreen_enable(_properties.get_x_size(), _properties.get_y_size()); } /** diff --git a/panda/src/windisplay/winGraphicsWindow.h b/panda/src/windisplay/winGraphicsWindow.h index a0a00966af..1dd857e6a6 100644 --- a/panda/src/windisplay/winGraphicsWindow.h +++ b/panda/src/windisplay/winGraphicsWindow.h @@ -109,8 +109,10 @@ protected: virtual void handle_reshape(); virtual bool do_fullscreen_resize(int x_size, int y_size); + bool do_fullscreen_switch(int x_size, int y_size); virtual bool do_fullscreen_switch(); virtual bool do_windowed_switch(); + bool do_fullscreen_enable(int x_size, int y_size); virtual bool do_fullscreen_enable(); virtual bool do_fullscreen_disable();