diff options
399 files changed, 9697 insertions, 4791 deletions
diff --git a/.github/actions/godot-deps/action.yml b/.github/actions/godot-deps/action.yml index eb9bdef1e7..bd9a1f55ed 100644 --- a/.github/actions/godot-deps/action.yml +++ b/.github/actions/godot-deps/action.yml @@ -27,6 +27,5 @@ runs: shell: bash run: | python -c "import sys; print(sys.version)" - python -m pip install wheel python -m pip install scons==${{ inputs.scons-version }} scons --version diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml index d516c37d16..950e1e51cc 100644 --- a/.github/workflows/android_builds.yml +++ b/.github/workflows/android_builds.yml @@ -14,7 +14,7 @@ concurrency: jobs: build-android: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 name: ${{ matrix.name }} strategy: fail-fast: false diff --git a/.github/workflows/godot_cpp_test.yml b/.github/workflows/godot_cpp_test.yml index e26c109d75..dc82a7cb3c 100644 --- a/.github/workflows/godot_cpp_test.yml +++ b/.github/workflows/godot_cpp_test.yml @@ -15,7 +15,7 @@ concurrency: jobs: godot-cpp-tests: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 name: Build and test Godot CPP steps: - name: Checkout diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index dc3d9f3786..bd4e2856e3 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -17,7 +17,8 @@ concurrency: jobs: build-linux: - runs-on: ubuntu-20.04 + # Stay one LTS before latest to increase portability of Linux artifacts. + runs-on: ubuntu-22.04 name: ${{ matrix.name }} strategy: fail-fast: false @@ -100,7 +101,7 @@ jobs: run: | sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EB8B81E14DA65431D7504EA8F63F0F2B90935439 - sudo add-apt-repository "deb https://ppa.launchpadcontent.net/kisak/turtle/ubuntu focal main" + sudo add-apt-repository "deb https://ppa.launchpadcontent.net/kisak/turtle/ubuntu ${{ matrix.os == 'ubuntu-20.04' && 'focal' || 'jammy' }} main" sudo apt-get install -qq mesa-vulkan-drivers # TODO: Figure out somehow how to embed this one. @@ -129,8 +130,8 @@ jobs: uses: ./.github/actions/godot-deps with: # Sync with Ensure*Version in SConstruct. - python-version: 3.6 - scons-version: 3.1.2 + python-version: 3.8 + scons-version: 4.0 - name: Setup GCC problem matcher uses: ammaraskar/gcc-problem-matcher@master diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml index ff102a06cc..9b326cb43e 100644 --- a/.github/workflows/static_checks.yml +++ b/.github/workflows/static_checks.yml @@ -9,7 +9,7 @@ concurrency: jobs: static-checks: name: Code style, file formatting, and docs - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/web_builds.yml b/.github/workflows/web_builds.yml index ec57fa2f0d..9ed8475769 100644 --- a/.github/workflows/web_builds.yml +++ b/.github/workflows/web_builds.yml @@ -15,7 +15,7 @@ concurrency: jobs: web-template: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 name: ${{ matrix.name }} strategy: fail-fast: false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d81c1043a7..2fa0493544 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -50,14 +50,14 @@ repos: stages: [manual] # Not automatically triggered, invoked via `pre-commit run --hook-stage manual clang-tidy` - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.6 + rev: v0.7.3 hooks: - id: ruff args: [--fix] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.11.2 + rev: v1.13.0 hooks: - id: mypy files: \.py$ diff --git a/SConstruct b/SConstruct index ee34d421e0..5a3a8f49eb 100644 --- a/SConstruct +++ b/SConstruct @@ -1,8 +1,8 @@ #!/usr/bin/env python from misc.utility.scons_hints import * -EnsureSConsVersion(3, 1, 2) -EnsurePythonVersion(3, 6) +EnsureSConsVersion(4, 0) +EnsurePythonVersion(3, 8) # System import atexit @@ -59,7 +59,7 @@ import glsl_builders import methods import scu_builders from methods import print_error, print_warning -from platform_methods import architecture_aliases, architectures +from platform_methods import architecture_aliases, architectures, compatibility_platform_aliases if ARGUMENTS.get("target", "editor") == "editor": _helper_module("editor.editor_builders", "editor/editor_builders.py") @@ -350,27 +350,16 @@ if env["platform"] == "": if env["platform"] != "": print(f'Automatically detected platform: {env["platform"]}') -if env["platform"] == "osx": - # Deprecated alias kept for compatibility. - print_warning('Platform "osx" has been renamed to "macos" in Godot 4. Building for platform "macos".') - env["platform"] = "macos" - -if env["platform"] == "iphone": - # Deprecated alias kept for compatibility. - print_warning('Platform "iphone" has been renamed to "ios" in Godot 4. Building for platform "ios".') - env["platform"] = "ios" - -if env["platform"] in ["linux", "bsd", "x11"]: - if env["platform"] == "x11": - # Deprecated alias kept for compatibility. - print_warning('Platform "x11" has been renamed to "linuxbsd" in Godot 4. Building for platform "linuxbsd".') - # Alias for convenience. - env["platform"] = "linuxbsd" +# Deprecated aliases kept for compatibility. +if env["platform"] in compatibility_platform_aliases: + alias = env["platform"] + platform = compatibility_platform_aliases[alias] + print_warning(f'Platform "{alias}" has been renamed to "{platform}" in Godot 4. Building for platform "{platform}".') + env["platform"] = platform -if env["platform"] == "javascript": - # Deprecated alias kept for compatibility. - print_warning('Platform "javascript" has been renamed to "web" in Godot 4. Building for platform "web".') - env["platform"] = "web" +# Alias for convenience. +if env["platform"] in ["linux", "bsd"]: + env["platform"] = "linuxbsd" if env["platform"] not in platform_list: text = "The following platforms are available:\n\t{}\n".format("\n\t".join(platform_list)) @@ -1055,18 +1044,7 @@ if scons_cache_path is not None: CacheDir(scons_cache_path) print("Scons cache enabled... (path: '" + scons_cache_path + "')") -if env["vsproj"]: - env.vs_incs = [] - env.vs_srcs = [] - if env["compiledb"]: - if env.scons_version < (4, 0, 0): - # Generating the compilation DB (`compile_commands.json`) requires SCons 4.0.0 or later. - print_error( - "The `compiledb=yes` option requires SCons 4.0 or later, but your version is %s." % scons_raw_version - ) - Exit(255) - env.Tool("compilation_db") env.Alias("compiledb", env.CompilationDatabase()) diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 092177bc15..fa0e4037ba 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -1408,7 +1408,7 @@ void ProjectSettings::_add_builtin_input_map() { } Dictionary action; - action["deadzone"] = Variant(0.2f); + action["deadzone"] = Variant(InputMap::DEFAULT_DEADZONE); action["events"] = events; String action_name = "input/" + E.key; diff --git a/core/core_bind.compat.inc b/core/core_bind.compat.inc index 3e8ac3c5de..22c78623da 100644 --- a/core/core_bind.compat.inc +++ b/core/core_bind.compat.inc @@ -44,11 +44,16 @@ void Semaphore::_bind_compatibility_methods() { // OS +String OS::_read_string_from_stdin_bind_compat_91201() { + return read_string_from_stdin(1024); +} + Dictionary OS::_execute_with_pipe_bind_compat_94434(const String &p_path, const Vector<String> &p_arguments) { return execute_with_pipe(p_path, p_arguments, true); } void OS::_bind_compatibility_methods() { + ClassDB::bind_compatibility_method(D_METHOD("read_string_from_stdin"), &OS::_read_string_from_stdin_bind_compat_91201); ClassDB::bind_compatibility_method(D_METHOD("execute_with_pipe", "path", "arguments"), &OS::_execute_with_pipe_bind_compat_94434); } diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 6ef466bee0..925551d933 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -132,6 +132,10 @@ ResourceUID::ID ResourceLoader::get_resource_uid(const String &p_path) { return ::ResourceLoader::get_resource_uid(p_path); } +Vector<String> ResourceLoader::list_directory(const String &p_directory) { + return ::ResourceLoader::list_directory(p_directory); +} + void ResourceLoader::_bind_methods() { ClassDB::bind_method(D_METHOD("load_threaded_request", "path", "type_hint", "use_sub_threads", "cache_mode"), &ResourceLoader::load_threaded_request, DEFVAL(""), DEFVAL(false), DEFVAL(CACHE_MODE_REUSE)); ClassDB::bind_method(D_METHOD("load_threaded_get_status", "path", "progress"), &ResourceLoader::load_threaded_get_status, DEFVAL_ARRAY); @@ -147,6 +151,7 @@ void ResourceLoader::_bind_methods() { ClassDB::bind_method(D_METHOD("get_cached_ref", "path"), &ResourceLoader::get_cached_ref); ClassDB::bind_method(D_METHOD("exists", "path", "type_hint"), &ResourceLoader::exists, DEFVAL("")); ClassDB::bind_method(D_METHOD("get_resource_uid", "path"), &ResourceLoader::get_resource_uid); + ClassDB::bind_method(D_METHOD("list_directory", "directory_path"), &ResourceLoader::list_directory); BIND_ENUM_CONSTANT(THREAD_LOAD_INVALID_RESOURCE); BIND_ENUM_CONSTANT(THREAD_LOAD_IN_PROGRESS); @@ -303,8 +308,24 @@ Error OS::shell_show_in_file_manager(const String &p_path, bool p_open_folder) { return ::OS::get_singleton()->shell_show_in_file_manager(p_path, p_open_folder); } -String OS::read_string_from_stdin() { - return ::OS::get_singleton()->get_stdin_string(); +String OS::read_string_from_stdin(int64_t p_buffer_size) { + return ::OS::get_singleton()->get_stdin_string(p_buffer_size); +} + +PackedByteArray OS::read_buffer_from_stdin(int64_t p_buffer_size) { + return ::OS::get_singleton()->get_stdin_buffer(p_buffer_size); +} + +OS::StdHandleType OS::get_stdin_type() const { + return (OS::StdHandleType)::OS::get_singleton()->get_stdin_type(); +} + +OS::StdHandleType OS::get_stdout_type() const { + return (OS::StdHandleType)::OS::get_singleton()->get_stdout_type(); +} + +OS::StdHandleType OS::get_stderr_type() const { + return (OS::StdHandleType)::OS::get_singleton()->get_stderr_type(); } int OS::execute(const String &p_path, const Vector<String> &p_arguments, Array r_output, bool p_read_stderr, bool p_open_console) { @@ -628,7 +649,13 @@ void OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_system_font_path", "font_name", "weight", "stretch", "italic"), &OS::get_system_font_path, DEFVAL(400), DEFVAL(100), DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_system_font_path_for_text", "font_name", "text", "locale", "script", "weight", "stretch", "italic"), &OS::get_system_font_path_for_text, DEFVAL(String()), DEFVAL(String()), DEFVAL(400), DEFVAL(100), DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_executable_path"), &OS::get_executable_path); - ClassDB::bind_method(D_METHOD("read_string_from_stdin"), &OS::read_string_from_stdin); + + ClassDB::bind_method(D_METHOD("read_string_from_stdin", "buffer_size"), &OS::read_string_from_stdin); + ClassDB::bind_method(D_METHOD("read_buffer_from_stdin", "buffer_size"), &OS::read_buffer_from_stdin); + ClassDB::bind_method(D_METHOD("get_stdin_type"), &OS::get_stdin_type); + ClassDB::bind_method(D_METHOD("get_stdout_type"), &OS::get_stdout_type); + ClassDB::bind_method(D_METHOD("get_stderr_type"), &OS::get_stderr_type); + ClassDB::bind_method(D_METHOD("execute", "path", "arguments", "output", "read_stderr", "open_console"), &OS::execute, DEFVAL_ARRAY, DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("execute_with_pipe", "path", "arguments", "blocking"), &OS::execute_with_pipe, DEFVAL(true)); ClassDB::bind_method(D_METHOD("create_process", "path", "arguments", "open_console"), &OS::create_process, DEFVAL(false)); @@ -720,6 +747,12 @@ void OS::_bind_methods() { BIND_ENUM_CONSTANT(SYSTEM_DIR_MUSIC); BIND_ENUM_CONSTANT(SYSTEM_DIR_PICTURES); BIND_ENUM_CONSTANT(SYSTEM_DIR_RINGTONES); + + BIND_ENUM_CONSTANT(STD_HANDLE_INVALID); + BIND_ENUM_CONSTANT(STD_HANDLE_CONSOLE); + BIND_ENUM_CONSTANT(STD_HANDLE_FILE); + BIND_ENUM_CONSTANT(STD_HANDLE_PIPE); + BIND_ENUM_CONSTANT(STD_HANDLE_UNKNOWN); } ////// Geometry2D ////// diff --git a/core/core_bind.h b/core/core_bind.h index 430ecdc906..d013e348bd 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -86,6 +86,8 @@ public: bool exists(const String &p_path, const String &p_type_hint = ""); ResourceUID::ID get_resource_uid(const String &p_path); + Vector<String> list_directory(const String &p_directory); + ResourceLoader() { singleton = this; } }; @@ -132,6 +134,7 @@ protected: #ifndef DISABLE_DEPRECATED Dictionary _execute_with_pipe_bind_compat_94434(const String &p_path, const Vector<String> &p_arguments); + String _read_string_from_stdin_bind_compat_91201(); static void _bind_compatibility_methods(); #endif @@ -146,6 +149,14 @@ public: PackedByteArray get_entropy(int p_bytes); String get_system_ca_certificates(); + enum StdHandleType { + STD_HANDLE_INVALID, + STD_HANDLE_CONSOLE, + STD_HANDLE_FILE, + STD_HANDLE_PIPE, + STD_HANDLE_UNKNOWN, + }; + virtual PackedStringArray get_connected_midi_inputs(); virtual void open_midi_inputs(); virtual void close_midi_inputs(); @@ -166,7 +177,13 @@ public: String get_system_font_path(const String &p_font_name, int p_weight = 400, int p_stretch = 100, bool p_italic = false) const; Vector<String> get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale = String(), const String &p_script = String(), int p_weight = 400, int p_stretch = 100, bool p_italic = false) const; String get_executable_path() const; - String read_string_from_stdin(); + + String read_string_from_stdin(int64_t p_buffer_size = 1024); + PackedByteArray read_buffer_from_stdin(int64_t p_buffer_size = 1024); + StdHandleType get_stdin_type() const; + StdHandleType get_stdout_type() const; + StdHandleType get_stderr_type() const; + int execute(const String &p_path, const Vector<String> &p_arguments, Array r_output = ClassDB::default_array_arg, bool p_read_stderr = false, bool p_open_console = false); Dictionary execute_with_pipe(const String &p_path, const Vector<String> &p_arguments, bool p_blocking = true); int create_process(const String &p_path, const Vector<String> &p_arguments, bool p_open_console = false); @@ -642,6 +659,7 @@ VARIANT_BITFIELD_CAST(core_bind::ResourceSaver::SaverFlags); VARIANT_ENUM_CAST(core_bind::OS::RenderingDriver); VARIANT_ENUM_CAST(core_bind::OS::SystemDir); +VARIANT_ENUM_CAST(core_bind::OS::StdHandleType); VARIANT_ENUM_CAST(core_bind::Geometry2D::PolyBooleanOperation); VARIANT_ENUM_CAST(core_bind::Geometry2D::PolyJoinType); diff --git a/core/debugger/local_debugger.cpp b/core/debugger/local_debugger.cpp index dc46ffc307..5e79a6d395 100644 --- a/core/debugger/local_debugger.cpp +++ b/core/debugger/local_debugger.cpp @@ -208,10 +208,10 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { print_variables(members, values, variable_prefix); } else if (line.begins_with("p") || line.begins_with("print")) { - if (line.get_slice_count(" ") <= 1) { - print_line("Usage: print <expre>"); + if (line.find_char(' ') < 0) { + print_line("Usage: print <expression>"); } else { - String expr = line.get_slicec(' ', 2); + String expr = line.split(" ", true, 1)[1]; String res = script_lang->debug_parse_stack_level_expression(current_frame, expr); print_line(res); } diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index d125bad252..4733aaf220 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -1097,7 +1097,7 @@ JoyAxis InputEventJoypadMotion::get_axis() const { void InputEventJoypadMotion::set_axis_value(float p_value) { axis_value = p_value; - pressed = Math::abs(axis_value) >= 0.5f; + pressed = Math::abs(axis_value) >= InputMap::DEFAULT_DEADZONE; emit_changed(); } diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index 6378f18545..954df36f3e 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -42,7 +42,7 @@ InputMap *InputMap::singleton = nullptr; void InputMap::_bind_methods() { ClassDB::bind_method(D_METHOD("has_action", "action"), &InputMap::has_action); ClassDB::bind_method(D_METHOD("get_actions"), &InputMap::_get_actions); - ClassDB::bind_method(D_METHOD("add_action", "action", "deadzone"), &InputMap::add_action, DEFVAL(0.2f)); + ClassDB::bind_method(D_METHOD("add_action", "action", "deadzone"), &InputMap::add_action, DEFVAL(DEFAULT_DEADZONE)); ClassDB::bind_method(D_METHOD("erase_action", "action"), &InputMap::erase_action); ClassDB::bind_method(D_METHOD("action_set_deadzone", "action", "deadzone"), &InputMap::action_set_deadzone); @@ -305,7 +305,7 @@ void InputMap::load_from_project_settings() { String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length()); Dictionary action = GLOBAL_GET(pi.name); - float deadzone = action.has("deadzone") ? (float)action["deadzone"] : 0.2f; + float deadzone = action.has("deadzone") ? (float)action["deadzone"] : DEFAULT_DEADZONE; Array events = action["events"]; add_action(name, deadzone); diff --git a/core/input/input_map.h b/core/input/input_map.h index 45798490f7..2b2a025332 100644 --- a/core/input/input_map.h +++ b/core/input/input_map.h @@ -49,6 +49,8 @@ public: List<Ref<InputEvent>> inputs; }; + static constexpr float DEFAULT_DEADZONE = 0.2f; + private: static InputMap *singleton; @@ -74,7 +76,7 @@ public: bool has_action(const StringName &p_action) const; List<StringName> get_actions() const; - void add_action(const StringName &p_action, float p_deadzone = 0.2); + void add_action(const StringName &p_action, float p_deadzone = DEFAULT_DEADZONE); void erase_action(const StringName &p_action); float action_get_deadzone(const StringName &p_action); diff --git a/core/io/file_access.compat.inc b/core/io/file_access.compat.inc new file mode 100644 index 0000000000..ed16050126 --- /dev/null +++ b/core/io/file_access.compat.inc @@ -0,0 +1,41 @@ +/**************************************************************************/ +/* file_access.compat.inc */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef DISABLE_DEPRECATED + +Ref<FileAccess> FileAccess::_open_encrypted_bind_compat_98918(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key) { + return open_encrypted(p_path, p_mode_flags, p_key, Vector<uint8_t>()); +} + +void FileAccess::_bind_compatibility_methods() { + ClassDB::bind_compatibility_static_method("FileAccess", D_METHOD("open_encrypted", "path", "mode_flags", "key"), &FileAccess::_open_encrypted_bind_compat_98918); +} + +#endif // DISABLE_DEPRECATED diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp index d8bf645a7d..dd826e626b 100644 --- a/core/io/file_access.cpp +++ b/core/io/file_access.cpp @@ -29,6 +29,7 @@ /**************************************************************************/ #include "file_access.h" +#include "file_access.compat.inc" #include "core/config/project_settings.h" #include "core/crypto/crypto_core.h" @@ -124,7 +125,7 @@ Ref<FileAccess> FileAccess::_open(const String &p_path, ModeFlags p_mode_flags) return fa; } -Ref<FileAccess> FileAccess::open_encrypted(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key) { +Ref<FileAccess> FileAccess::open_encrypted(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key, const Vector<uint8_t> &p_iv) { Ref<FileAccess> fa = _open(p_path, p_mode_flags); if (fa.is_null()) { return fa; @@ -132,7 +133,7 @@ Ref<FileAccess> FileAccess::open_encrypted(const String &p_path, ModeFlags p_mod Ref<FileAccessEncrypted> fae; fae.instantiate(); - Error err = fae->open_and_parse(fa, p_key, (p_mode_flags == WRITE) ? FileAccessEncrypted::MODE_WRITE_AES256 : FileAccessEncrypted::MODE_READ); + Error err = fae->open_and_parse(fa, p_key, (p_mode_flags == WRITE) ? FileAccessEncrypted::MODE_WRITE_AES256 : FileAccessEncrypted::MODE_READ, true, p_iv); last_file_open_error = err; if (err) { return Ref<FileAccess>(); @@ -806,7 +807,7 @@ String FileAccess::get_sha256(const String &p_file) { void FileAccess::_bind_methods() { ClassDB::bind_static_method("FileAccess", D_METHOD("open", "path", "flags"), &FileAccess::_open); - ClassDB::bind_static_method("FileAccess", D_METHOD("open_encrypted", "path", "mode_flags", "key"), &FileAccess::open_encrypted); + ClassDB::bind_static_method("FileAccess", D_METHOD("open_encrypted", "path", "mode_flags", "key", "iv"), &FileAccess::open_encrypted, DEFVAL(Vector<uint8_t>())); ClassDB::bind_static_method("FileAccess", D_METHOD("open_encrypted_with_pass", "path", "mode_flags", "pass"), &FileAccess::open_encrypted_pass); ClassDB::bind_static_method("FileAccess", D_METHOD("open_compressed", "path", "mode_flags", "compression_mode"), &FileAccess::open_compressed, DEFVAL(0)); ClassDB::bind_static_method("FileAccess", D_METHOD("get_open_error"), &FileAccess::get_open_error); diff --git a/core/io/file_access.h b/core/io/file_access.h index 7f5687fe03..88c8110a51 100644 --- a/core/io/file_access.h +++ b/core/io/file_access.h @@ -109,6 +109,12 @@ protected: static FileCloseFailNotify close_fail_notify; +#ifndef DISABLE_DEPRECATED + static Ref<FileAccess> _open_encrypted_bind_compat_98918(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key); + + static void _bind_compatibility_methods(); +#endif + private: static bool backup_save; thread_local static Error last_file_open_error; @@ -199,7 +205,7 @@ public: static Ref<FileAccess> create_for_path(const String &p_path); static Ref<FileAccess> open(const String &p_path, int p_mode_flags, Error *r_error = nullptr); /// Create a file access (for the current platform) this is the only portable way of accessing files. - static Ref<FileAccess> open_encrypted(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key); + static Ref<FileAccess> open_encrypted(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key, const Vector<uint8_t> &p_iv = Vector<uint8_t>()); static Ref<FileAccess> open_encrypted_pass(const String &p_path, ModeFlags p_mode_flags, const String &p_pass); static Ref<FileAccess> open_compressed(const String &p_path, ModeFlags p_mode_flags, CompressionMode p_compress_mode = COMPRESSION_FASTLZ); static Error get_open_error(); diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 24be9ef230..ba26f2e07b 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -36,7 +36,7 @@ #include <stdio.h> -Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic) { +Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic, const Vector<uint8_t> &p_iv) { ERR_FAIL_COND_V_MSG(file.is_valid(), ERR_ALREADY_IN_USE, vformat("Can't open file while another file from path '%s' is open.", file->get_path_absolute())); ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER); @@ -49,6 +49,16 @@ Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<u writing = true; file = p_base; key = p_key; + if (p_iv.is_empty()) { + iv.resize(16); + CryptoCore::RandomGenerator rng; + ERR_FAIL_COND_V_MSG(rng.init(), FAILED, "Failed to initialize random number generator."); + Error err = rng.get_random_bytes(iv.ptrw(), 16); + ERR_FAIL_COND_V(err != OK, err); + } else { + ERR_FAIL_COND_V(p_iv.size() != 16, ERR_INVALID_PARAMETER); + iv = p_iv; + } } else if (p_mode == MODE_READ) { writing = false; @@ -63,10 +73,8 @@ Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<u p_base->get_buffer(md5d, 16); length = p_base->get_64(); - unsigned char iv[16]; - for (int i = 0; i < 16; i++) { - iv[i] = p_base->get_8(); - } + iv.resize(16); + p_base->get_buffer(iv.ptrw(), 16); base = p_base->get_position(); ERR_FAIL_COND_V(p_base->get_length() < base + length, ERR_FILE_CORRUPT); @@ -83,7 +91,7 @@ Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<u CryptoCore::AESContext ctx; ctx.set_encode_key(key.ptrw(), 256); // Due to the nature of CFB, same key schedule is used for both encryption and decryption! - ctx.decrypt_cfb(ds, iv, data.ptrw(), data.ptrw()); + ctx.decrypt_cfb(ds, iv.ptrw(), data.ptrw(), data.ptrw()); } data.resize(length); @@ -145,14 +153,9 @@ void FileAccessEncrypted::_close() { file->store_buffer(hash, 16); file->store_64(data.size()); + file->store_buffer(iv.ptr(), 16); - unsigned char iv[16]; - for (int i = 0; i < 16; i++) { - iv[i] = Math::rand() % 256; - file->store_8(iv[i]); - } - - ctx.encrypt_cfb(len, iv, compressed.ptrw(), compressed.ptrw()); + ctx.encrypt_cfb(len, iv.ptrw(), compressed.ptrw(), compressed.ptrw()); file->store_buffer(compressed.ptr(), compressed.size()); data.clear(); diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h index 5f8c803d60..63a8cab145 100644 --- a/core/io/file_access_encrypted.h +++ b/core/io/file_access_encrypted.h @@ -44,6 +44,7 @@ public: }; private: + Vector<uint8_t> iv; Vector<uint8_t> key; bool writing = false; Ref<FileAccess> file; @@ -57,9 +58,11 @@ private: void _close(); public: - Error open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic = true); + Error open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic = true, const Vector<uint8_t> &p_iv = Vector<uint8_t>()); Error open_and_parse_password(Ref<FileAccess> p_base, const String &p_key, Mode p_mode); + Vector<uint8_t> get_iv() const { return iv; } + virtual Error open_internal(const String &p_path, int p_mode_flags) override; ///< open a file virtual bool is_open() const override; ///< true when file is open diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index bfd1a53f3e..b9af1bfb57 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -48,7 +48,7 @@ Error PackedData::add_pack(const String &p_path, bool p_replace_files, uint64_t } void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64_t p_ofs, uint64_t p_size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted) { - String simplified_path = p_path.simplify_path(); + String simplified_path = p_path.simplify_path().trim_prefix("res://"); PathMD5 pmd5(simplified_path.md5_buffer()); bool exists = files.has(pmd5); @@ -68,13 +68,11 @@ void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64 } if (!exists) { - //search for dir - String p = simplified_path.replace_first("res://", ""); + // Search for directory. PackedDir *cd = root; - if (p.contains("/")) { //in a subdir - - Vector<String> ds = p.get_base_dir().split("/"); + if (simplified_path.contains("/")) { // In a subdirectory. + Vector<String> ds = simplified_path.get_base_dir().split("/"); for (int j = 0; j < ds.size(); j++) { if (!cd->subdirs.has(ds[j])) { @@ -89,13 +87,40 @@ void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64 } } String filename = simplified_path.get_file(); - // Don't add as a file if the path points to a directory + // Don't add as a file if the path points to a directory. if (!filename.is_empty()) { cd->files.insert(filename); } } } +void PackedData::remove_path(const String &p_path) { + String simplified_path = p_path.simplify_path().trim_prefix("res://"); + PathMD5 pmd5(simplified_path.md5_buffer()); + if (!files.has(pmd5)) { + return; + } + + // Search for directory. + PackedDir *cd = root; + + if (simplified_path.contains("/")) { // In a subdirectory. + Vector<String> ds = simplified_path.get_base_dir().split("/"); + + for (int j = 0; j < ds.size(); j++) { + if (!cd->subdirs.has(ds[j])) { + return; // Subdirectory does not exist, do not bother creating. + } else { + cd = cd->subdirs[ds[j]]; + } + } + } + + cd->files.erase(simplified_path.get_file()); + + files.erase(pmd5); +} + void PackedData::add_pack_source(PackSource *p_source) { if (p_source != nullptr) { sources.push_back(p_source); @@ -103,15 +128,32 @@ void PackedData::add_pack_source(PackSource *p_source) { } uint8_t *PackedData::get_file_hash(const String &p_path) { - PathMD5 pmd5(p_path.md5_buffer()); + String simplified_path = p_path.simplify_path().trim_prefix("res://"); + PathMD5 pmd5(simplified_path.md5_buffer()); HashMap<PathMD5, PackedFile, PathMD5>::Iterator E = files.find(pmd5); - if (!E || E->value.offset == 0) { + if (!E) { return nullptr; } return E->value.md5; } +HashSet<String> PackedData::get_file_paths() const { + HashSet<String> file_paths; + _get_file_paths(root, root->name, file_paths); + return file_paths; +} + +void PackedData::_get_file_paths(PackedDir *p_dir, const String &p_parent_dir, HashSet<String> &r_paths) const { + for (const String &E : p_dir->files) { + r_paths.insert(p_parent_dir.path_join(E)); + } + + for (const KeyValue<String, PackedDir *> &E : p_dir->subdirs) { + _get_file_paths(E.value, p_parent_dir.path_join(E.key), r_paths); + } +} + void PackedData::clear() { files.clear(); _free_packed_dirs(root); @@ -269,13 +311,17 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, String path; path.parse_utf8(cs.ptr()); - uint64_t ofs = file_base + f->get_64(); + uint64_t ofs = f->get_64(); uint64_t size = f->get_64(); uint8_t md5[16]; f->get_buffer(md5, 16); uint32_t flags = f->get_32(); - PackedData::get_singleton()->add_path(p_path, path, ofs + p_offset, size, md5, this, p_replace_files, (flags & PACK_FILE_ENCRYPTED)); + if (flags & PACK_FILE_REMOVAL) { // The file was removed. + PackedData::get_singleton()->remove_path(path); + } else { + PackedData::get_singleton()->add_path(p_path, path, file_base + ofs + p_offset, size, md5, this, p_replace_files, (flags & PACK_FILE_ENCRYPTED)); + } } return true; diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index 57b7a5f87f..b957a43de2 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -49,7 +49,8 @@ enum PackFlags { }; enum PackFileFlags { - PACK_FILE_ENCRYPTED = 1 << 0 + PACK_FILE_ENCRYPTED = 1 << 0, + PACK_FILE_REMOVAL = 1 << 1, }; class PackSource; @@ -107,11 +108,14 @@ private: bool disabled = false; void _free_packed_dirs(PackedDir *p_dir); + void _get_file_paths(PackedDir *p_dir, const String &p_parent_dir, HashSet<String> &r_paths) const; public: void add_pack_source(PackSource *p_source); void add_path(const String &p_pkg_path, const String &p_path, uint64_t p_ofs, uint64_t p_size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted = false); // for PackSource + void remove_path(const String &p_path); uint8_t *get_file_hash(const String &p_path); + HashSet<String> get_file_paths() const; void set_disabled(bool p_disabled) { disabled = p_disabled; } _FORCE_INLINE_ bool is_disabled() const { return disabled; } @@ -190,21 +194,18 @@ public: }; Ref<FileAccess> PackedData::try_open_path(const String &p_path) { - String simplified_path = p_path.simplify_path(); + String simplified_path = p_path.simplify_path().trim_prefix("res://"); PathMD5 pmd5(simplified_path.md5_buffer()); HashMap<PathMD5, PackedFile, PathMD5>::Iterator E = files.find(pmd5); if (!E) { - return nullptr; //not found - } - if (E->value.offset == 0) { - return nullptr; //was erased + return nullptr; // Not found. } return E->value.src->get_file(p_path, &E->value); } bool PackedData::has_path(const String &p_path) { - return files.has(PathMD5(p_path.simplify_path().md5_buffer())); + return files.has(PathMD5(p_path.simplify_path().trim_prefix("res://").md5_buffer())); } bool PackedData::has_directory(const String &p_path) { diff --git a/core/io/http_client_tcp.cpp b/core/io/http_client_tcp.cpp index 70fcad543a..237ba30a80 100644 --- a/core/io/http_client_tcp.cpp +++ b/core/io/http_client_tcp.cpp @@ -662,15 +662,16 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() { chunk_left -= rec; if (chunk_left == 0) { - if (chunk[chunk.size() - 2] != '\r' || chunk[chunk.size() - 1] != '\n') { + const int chunk_size = chunk.size(); + if (chunk[chunk_size - 2] != '\r' || chunk[chunk_size - 1] != '\n') { ERR_PRINT("HTTP Invalid chunk terminator (not \\r\\n)"); status = STATUS_CONNECTION_ERROR; break; } - ret.resize(chunk.size() - 2); + ret.resize(chunk_size - 2); uint8_t *w = ret.ptrw(); - memcpy(w, chunk.ptr(), chunk.size() - 2); + memcpy(w, chunk.ptr(), chunk_size - 2); chunk.clear(); } diff --git a/core/io/image.cpp b/core/io/image.cpp index 9b5bb058ef..fbf37cbee7 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -44,24 +44,24 @@ #include <cmath> const char *Image::format_names[Image::FORMAT_MAX] = { - "Lum8", //luminance - "LumAlpha8", //luminance-alpha + "Lum8", + "LumAlpha8", "Red8", "RedGreen", "RGB8", "RGBA8", "RGBA4444", - "RGBA5551", - "RFloat", //float + "RGBA5551", // Actually RGB565, kept as RGBA5551 for compatibility. + "RFloat", "RGFloat", "RGBFloat", "RGBAFloat", - "RHalf", //half float + "RHalf", "RGHalf", "RGBHalf", "RGBAHalf", "RGBE9995", - "DXT1 RGB8", //s3tc + "DXT1 RGB8", "DXT3 RGBA8", "DXT5 RGBA8", "RGTC Red8", @@ -69,9 +69,9 @@ const char *Image::format_names[Image::FORMAT_MAX] = { "BPTC_RGBA", "BPTC_RGBF", "BPTC_RGBFU", - "ETC", //etc1 - "ETC2_R11", //etc2 - "ETC2_R11S", //signed", NOT srgb. + "ETC", + "ETC2_R11", + "ETC2_R11S", "ETC2_RG11", "ETC2_RG11S", "ETC2_RGB8", @@ -85,17 +85,60 @@ const char *Image::format_names[Image::FORMAT_MAX] = { "ASTC_8x8_HDR", }; +// External saver function pointers. + SavePNGFunc Image::save_png_func = nullptr; SaveJPGFunc Image::save_jpg_func = nullptr; SaveEXRFunc Image::save_exr_func = nullptr; +SaveWebPFunc Image::save_webp_func = nullptr; SavePNGBufferFunc Image::save_png_buffer_func = nullptr; -SaveEXRBufferFunc Image::save_exr_buffer_func = nullptr; SaveJPGBufferFunc Image::save_jpg_buffer_func = nullptr; - -SaveWebPFunc Image::save_webp_func = nullptr; +SaveEXRBufferFunc Image::save_exr_buffer_func = nullptr; SaveWebPBufferFunc Image::save_webp_buffer_func = nullptr; +// External loader function pointers. + +ImageMemLoadFunc Image::_png_mem_loader_func = nullptr; +ImageMemLoadFunc Image::_png_mem_unpacker_func = nullptr; +ImageMemLoadFunc Image::_jpg_mem_loader_func = nullptr; +ImageMemLoadFunc Image::_webp_mem_loader_func = nullptr; +ImageMemLoadFunc Image::_tga_mem_loader_func = nullptr; +ImageMemLoadFunc Image::_bmp_mem_loader_func = nullptr; +ScalableImageMemLoadFunc Image::_svg_scalable_mem_loader_func = nullptr; +ImageMemLoadFunc Image::_ktx_mem_loader_func = nullptr; + +// External VRAM compression function pointers. + +void (*Image::_image_compress_bc_func)(Image *, Image::UsedChannels) = nullptr; +void (*Image::_image_compress_bptc_func)(Image *, Image::UsedChannels) = nullptr; +void (*Image::_image_compress_etc1_func)(Image *) = nullptr; +void (*Image::_image_compress_etc2_func)(Image *, Image::UsedChannels) = nullptr; +void (*Image::_image_compress_astc_func)(Image *, Image::ASTCFormat) = nullptr; + +Error (*Image::_image_compress_bptc_rd_func)(Image *, Image::UsedChannels) = nullptr; +Error (*Image::_image_compress_bc_rd_func)(Image *, Image::UsedChannels) = nullptr; + +// External VRAM decompression function pointers. + +void (*Image::_image_decompress_bc)(Image *) = nullptr; +void (*Image::_image_decompress_bptc)(Image *) = nullptr; +void (*Image::_image_decompress_etc1)(Image *) = nullptr; +void (*Image::_image_decompress_etc2)(Image *) = nullptr; +void (*Image::_image_decompress_astc)(Image *) = nullptr; + +// External packer function pointers. + +Vector<uint8_t> (*Image::webp_lossy_packer)(const Ref<Image> &, float) = nullptr; +Vector<uint8_t> (*Image::webp_lossless_packer)(const Ref<Image> &) = nullptr; +Vector<uint8_t> (*Image::png_packer)(const Ref<Image> &) = nullptr; +Vector<uint8_t> (*Image::basis_universal_packer)(const Ref<Image> &, Image::UsedChannels) = nullptr; + +Ref<Image> (*Image::webp_unpacker)(const Vector<uint8_t> &) = nullptr; +Ref<Image> (*Image::png_unpacker)(const Vector<uint8_t> &) = nullptr; +Ref<Image> (*Image::basis_universal_unpacker)(const Vector<uint8_t> &) = nullptr; +Ref<Image> (*Image::basis_universal_unpacker_ptr)(const uint8_t *, int) = nullptr; + void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixel_size, uint8_t *p_data, const uint8_t *p_pixel) { uint32_t ofs = (p_y * width + p_x) * p_pixel_size; memcpy(p_data + ofs, p_pixel, p_pixel_size); @@ -109,9 +152,9 @@ void Image::_get_pixelb(int p_x, int p_y, uint32_t p_pixel_size, const uint8_t * int Image::get_format_pixel_size(Format p_format) { switch (p_format) { case FORMAT_L8: - return 1; //luminance + return 1; case FORMAT_LA8: - return 2; //luminance-alpha + return 2; case FORMAT_R8: return 1; case FORMAT_RG8: @@ -125,7 +168,7 @@ int Image::get_format_pixel_size(Format p_format) { case FORMAT_RGB565: return 2; case FORMAT_RF: - return 4; //float + return 4; case FORMAT_RGF: return 8; case FORMAT_RGBF: @@ -133,7 +176,7 @@ int Image::get_format_pixel_size(Format p_format) { case FORMAT_RGBAF: return 16; case FORMAT_RH: - return 2; //half float + return 2; case FORMAT_RGH: return 4; case FORMAT_RGBH: @@ -143,27 +186,27 @@ int Image::get_format_pixel_size(Format p_format) { case FORMAT_RGBE9995: return 4; case FORMAT_DXT1: - return 1; //s3tc bc1 + return 1; case FORMAT_DXT3: - return 1; //bc2 + return 1; case FORMAT_DXT5: - return 1; //bc3 + return 1; case FORMAT_RGTC_R: - return 1; //bc4 + return 1; case FORMAT_RGTC_RG: - return 1; //bc5 + return 1; case FORMAT_BPTC_RGBA: - return 1; //btpc bc6h + return 1; case FORMAT_BPTC_RGBF: - return 1; //float / + return 1; case FORMAT_BPTC_RGBFU: - return 1; //unsigned float + return 1; case FORMAT_ETC: - return 1; //etc1 + return 1; case FORMAT_ETC2_R11: - return 1; //etc2 + return 1; case FORMAT_ETC2_R11S: - return 1; //signed: return 1; NOT srgb. + return 1; case FORMAT_ETC2_RG11: return 1; case FORMAT_ETC2_RG11S: @@ -194,12 +237,11 @@ int Image::get_format_pixel_size(Format p_format) { void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) { switch (p_format) { - case FORMAT_DXT1: //s3tc bc1 - case FORMAT_DXT3: //bc2 - case FORMAT_DXT5: //bc3 - case FORMAT_RGTC_R: //bc4 - case FORMAT_RGTC_RG: { //bc5 case case FORMAT_DXT1: - + case FORMAT_DXT1: + case FORMAT_DXT3: + case FORMAT_DXT5: + case FORMAT_RGTC_R: + case FORMAT_RGTC_RG: { r_w = 4; r_h = 4; } break; @@ -213,8 +255,8 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) { r_w = 4; r_h = 4; } break; - case FORMAT_ETC2_R11: //etc2 - case FORMAT_ETC2_R11S: //signed: NOT srgb. + case FORMAT_ETC2_R11: + case FORMAT_ETC2_R11S: case FORMAT_ETC2_RG11: case FORMAT_ETC2_RG11S: case FORMAT_ETC2_RGB8: @@ -224,19 +266,16 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) { case FORMAT_DXT5_RA_AS_RG: { r_w = 4; r_h = 4; - } break; case FORMAT_ASTC_4x4: case FORMAT_ASTC_4x4_HDR: { r_w = 4; r_h = 4; - } break; case FORMAT_ASTC_8x8: case FORMAT_ASTC_8x8_HDR: { r_w = 8; r_h = 8; - } break; default: { r_w = 1; @@ -257,12 +296,11 @@ int Image::get_format_pixel_rshift(Format p_format) { int Image::get_format_block_size(Format p_format) { switch (p_format) { - case FORMAT_DXT1: //s3tc bc1 - case FORMAT_DXT3: //bc2 - case FORMAT_DXT5: //bc3 - case FORMAT_RGTC_R: //bc4 - case FORMAT_RGTC_RG: { //bc5 case case FORMAT_DXT1: - + case FORMAT_DXT1: + case FORMAT_DXT3: + case FORMAT_DXT5: + case FORMAT_RGTC_R: + case FORMAT_RGTC_RG: { return 4; } case FORMAT_ETC: { @@ -273,17 +311,15 @@ int Image::get_format_block_size(Format p_format) { case FORMAT_BPTC_RGBFU: { return 4; } - case FORMAT_ETC2_R11: //etc2 - case FORMAT_ETC2_R11S: //signed: NOT srgb. + case FORMAT_ETC2_R11: + case FORMAT_ETC2_R11S: case FORMAT_ETC2_RG11: case FORMAT_ETC2_RG11S: case FORMAT_ETC2_RGB8: case FORMAT_ETC2_RGBA8: case FORMAT_ETC2_RGB8A1: - case FORMAT_ETC2_RA_AS_RG: //used to make basis universal happy - case FORMAT_DXT5_RA_AS_RG: //used to make basis universal happy - - { + case FORMAT_ETC2_RA_AS_RG: + case FORMAT_DXT5_RA_AS_RG: { return 4; } case FORMAT_ASTC_4x4: @@ -459,7 +495,7 @@ int Image::get_mipmap_count() const { } } -//using template generates perfectly optimized code due to constant expression reduction and unused variable removal present in all compilers +// Using template generates perfectly optimized code due to constant expression reduction and unused variable removal present in all compilers. template <uint32_t read_bytes, bool read_alpha, uint32_t write_bytes, bool write_alpha, bool read_gray, bool write_gray> static void _convert(int p_width, int p_height, const uint8_t *p_src, uint8_t *p_dst) { constexpr uint32_t max_bytes = MAX(read_bytes, write_bytes); @@ -551,7 +587,7 @@ void Image::convert(Format p_new_format) { ERR_FAIL_MSG("Cannot convert to <-> from compressed formats. Use compress() and decompress() instead."); } else if (!_are_formats_compatible(format, p_new_format)) { - //use put/set pixel which is slower but works with non byte formats + // Use put/set pixel which is slower but works with non-byte formats. Image new_img(width, height, mipmaps, p_new_format); for (int mip = 0; mip < mipmap_count; mip++) { @@ -1694,7 +1730,7 @@ void Image::flip_x() { } } -/// Get mipmap size and offset. +// Get mipmap size and offset. int64_t Image::_get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps, int *r_mm_width, int *r_mm_height) { // Data offset in mipmaps (including the original texture). int64_t size = 0; @@ -3134,37 +3170,6 @@ void Image::fill_rect(const Rect2i &p_rect, const Color &p_color) { } } -ImageMemLoadFunc Image::_png_mem_loader_func = nullptr; -ImageMemLoadFunc Image::_png_mem_unpacker_func = nullptr; -ImageMemLoadFunc Image::_jpg_mem_loader_func = nullptr; -ImageMemLoadFunc Image::_webp_mem_loader_func = nullptr; -ImageMemLoadFunc Image::_tga_mem_loader_func = nullptr; -ImageMemLoadFunc Image::_bmp_mem_loader_func = nullptr; -ScalableImageMemLoadFunc Image::_svg_scalable_mem_loader_func = nullptr; -ImageMemLoadFunc Image::_ktx_mem_loader_func = nullptr; - -void (*Image::_image_compress_bc_func)(Image *, Image::UsedChannels) = nullptr; -void (*Image::_image_compress_bptc_func)(Image *, Image::UsedChannels) = nullptr; -void (*Image::_image_compress_etc1_func)(Image *) = nullptr; -void (*Image::_image_compress_etc2_func)(Image *, Image::UsedChannels) = nullptr; -void (*Image::_image_compress_astc_func)(Image *, Image::ASTCFormat) = nullptr; -Error (*Image::_image_compress_bptc_rd_func)(Image *, Image::UsedChannels) = nullptr; -Error (*Image::_image_compress_bc_rd_func)(Image *, Image::UsedChannels) = nullptr; -void (*Image::_image_decompress_bc)(Image *) = nullptr; -void (*Image::_image_decompress_bptc)(Image *) = nullptr; -void (*Image::_image_decompress_etc1)(Image *) = nullptr; -void (*Image::_image_decompress_etc2)(Image *) = nullptr; -void (*Image::_image_decompress_astc)(Image *) = nullptr; - -Vector<uint8_t> (*Image::webp_lossy_packer)(const Ref<Image> &, float) = nullptr; -Vector<uint8_t> (*Image::webp_lossless_packer)(const Ref<Image> &) = nullptr; -Ref<Image> (*Image::webp_unpacker)(const Vector<uint8_t> &) = nullptr; -Vector<uint8_t> (*Image::png_packer)(const Ref<Image> &) = nullptr; -Ref<Image> (*Image::png_unpacker)(const Vector<uint8_t> &) = nullptr; -Vector<uint8_t> (*Image::basis_universal_packer)(const Ref<Image> &, Image::UsedChannels) = nullptr; -Ref<Image> (*Image::basis_universal_unpacker)(const Vector<uint8_t> &) = nullptr; -Ref<Image> (*Image::basis_universal_unpacker_ptr)(const uint8_t *, int) = nullptr; - void Image::_set_data(const Dictionary &p_data) { ERR_FAIL_COND(!p_data.has("width")); ERR_FAIL_COND(!p_data.has("height")); @@ -3204,6 +3209,14 @@ Color Image::get_pixelv(const Point2i &p_point) const { return get_pixel(p_point.x, p_point.y); } +void Image::_copy_internals_from(const Image &p_image) { + format = p_image.format; + width = p_image.width; + height = p_image.height; + mipmaps = p_image.mipmaps; + data = p_image.data; +} + Color Image::_get_color_at_ofs(const uint8_t *ptr, uint32_t ofs) const { switch (format) { case FORMAT_L8: { @@ -3643,34 +3656,34 @@ void Image::_bind_methods() { BIND_CONSTANT(MAX_WIDTH); BIND_CONSTANT(MAX_HEIGHT); - BIND_ENUM_CONSTANT(FORMAT_L8); //luminance - BIND_ENUM_CONSTANT(FORMAT_LA8); //luminance-alpha + BIND_ENUM_CONSTANT(FORMAT_L8); + BIND_ENUM_CONSTANT(FORMAT_LA8); BIND_ENUM_CONSTANT(FORMAT_R8); BIND_ENUM_CONSTANT(FORMAT_RG8); BIND_ENUM_CONSTANT(FORMAT_RGB8); BIND_ENUM_CONSTANT(FORMAT_RGBA8); BIND_ENUM_CONSTANT(FORMAT_RGBA4444); BIND_ENUM_CONSTANT(FORMAT_RGB565); - BIND_ENUM_CONSTANT(FORMAT_RF); //float + BIND_ENUM_CONSTANT(FORMAT_RF); BIND_ENUM_CONSTANT(FORMAT_RGF); BIND_ENUM_CONSTANT(FORMAT_RGBF); BIND_ENUM_CONSTANT(FORMAT_RGBAF); - BIND_ENUM_CONSTANT(FORMAT_RH); //half float + BIND_ENUM_CONSTANT(FORMAT_RH); BIND_ENUM_CONSTANT(FORMAT_RGH); BIND_ENUM_CONSTANT(FORMAT_RGBH); BIND_ENUM_CONSTANT(FORMAT_RGBAH); BIND_ENUM_CONSTANT(FORMAT_RGBE9995); - BIND_ENUM_CONSTANT(FORMAT_DXT1); //s3tc bc1 - BIND_ENUM_CONSTANT(FORMAT_DXT3); //bc2 - BIND_ENUM_CONSTANT(FORMAT_DXT5); //bc3 + BIND_ENUM_CONSTANT(FORMAT_DXT1); + BIND_ENUM_CONSTANT(FORMAT_DXT3); + BIND_ENUM_CONSTANT(FORMAT_DXT5); BIND_ENUM_CONSTANT(FORMAT_RGTC_R); BIND_ENUM_CONSTANT(FORMAT_RGTC_RG); - BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBA); //btpc bc6h - BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBF); //float / - BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBFU); //unsigned float - BIND_ENUM_CONSTANT(FORMAT_ETC); //etc1 - BIND_ENUM_CONSTANT(FORMAT_ETC2_R11); //etc2 - BIND_ENUM_CONSTANT(FORMAT_ETC2_R11S); //signed ); NOT srgb. + BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBA); + BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBF); + BIND_ENUM_CONSTANT(FORMAT_BPTC_RGBFU); + BIND_ENUM_CONSTANT(FORMAT_ETC); + BIND_ENUM_CONSTANT(FORMAT_ETC2_R11); + BIND_ENUM_CONSTANT(FORMAT_ETC2_R11S); BIND_ENUM_CONSTANT(FORMAT_ETC2_RG11); BIND_ENUM_CONSTANT(FORMAT_ETC2_RG11S); BIND_ENUM_CONSTANT(FORMAT_ETC2_RGB8); @@ -4177,7 +4190,7 @@ void Image::renormalize_half(uint16_t *p_rgb) { } void Image::renormalize_rgbe9995(uint32_t *p_rgb) { - // Never used + // Never used. } Image::Image(const uint8_t *p_mem_png_jpg, int p_len) { @@ -4210,6 +4223,15 @@ void Image::set_as_black() { memset(data.ptrw(), 0, data.size()); } +void Image::copy_internals_from(const Ref<Image> &p_image) { + ERR_FAIL_COND_MSG(p_image.is_null(), "Cannot copy image internals: invalid Image object."); + format = p_image->format; + width = p_image->width; + height = p_image->height; + mipmaps = p_image->mipmaps; + data = p_image->data; +} + Dictionary Image::compute_image_metrics(const Ref<Image> p_compared_image, bool p_luma_metric) { // https://github.com/richgel999/bc7enc_rdo/blob/master/LICENSE // @@ -4250,8 +4272,6 @@ Dictionary Image::compute_image_metrics(const Ref<Image> p_compared_image, bool } ERR_FAIL_COND_V(err != OK, result); - ERR_FAIL_COND_V(err != OK, result); - ERR_FAIL_COND_V_MSG((compared_image->get_format() >= Image::FORMAT_RH) && (compared_image->get_format() <= Image::FORMAT_RGBE9995), result, "Metrics on HDR images are not supported."); ERR_FAIL_COND_V_MSG((source_image->get_format() >= Image::FORMAT_RH) && (source_image->get_format() <= Image::FORMAT_RGBE9995), result, "Metrics on HDR images are not supported."); diff --git a/core/io/image.h b/core/io/image.h index 78757246e0..3149314ad8 100644 --- a/core/io/image.h +++ b/core/io/image.h @@ -43,12 +43,17 @@ class Image; +// Function pointer prototypes. + typedef Error (*SavePNGFunc)(const String &p_path, const Ref<Image> &p_img); typedef Vector<uint8_t> (*SavePNGBufferFunc)(const Ref<Image> &p_img); + typedef Error (*SaveJPGFunc)(const String &p_path, const Ref<Image> &p_img, float p_quality); typedef Vector<uint8_t> (*SaveJPGBufferFunc)(const Ref<Image> &p_img, float p_quality); + typedef Ref<Image> (*ImageMemLoadFunc)(const uint8_t *p_png, int p_size); typedef Ref<Image> (*ScalableImageMemLoadFunc)(const uint8_t *p_data, int p_size, float p_scale); + typedef Error (*SaveWebPFunc)(const String &p_path, const Ref<Image> &p_img, const bool p_lossy, const float p_quality); typedef Vector<uint8_t> (*SaveWebPBufferFunc)(const Ref<Image> &p_img, const bool p_lossy, const float p_quality); @@ -59,57 +64,48 @@ class Image : public Resource { GDCLASS(Image, Resource); public: - static SavePNGFunc save_png_func; - static SaveJPGFunc save_jpg_func; - static SaveEXRFunc save_exr_func; - static SavePNGBufferFunc save_png_buffer_func; - static SaveEXRBufferFunc save_exr_buffer_func; - static SaveJPGBufferFunc save_jpg_buffer_func; - static SaveWebPFunc save_webp_func; - static SaveWebPBufferFunc save_webp_buffer_func; - enum { - MAX_WIDTH = (1 << 24), // force a limit somehow - MAX_HEIGHT = (1 << 24), // force a limit somehow - MAX_PIXELS = 268435456 + MAX_WIDTH = (1 << 24), // Force a limit somehow. + MAX_HEIGHT = (1 << 24), // Force a limit somehow. + MAX_PIXELS = 268435456 // 16384 ^ 2 }; enum Format { - FORMAT_L8, //luminance - FORMAT_LA8, //luminance-alpha + FORMAT_L8, // Luminance + FORMAT_LA8, // Luminance-Alpha FORMAT_R8, FORMAT_RG8, FORMAT_RGB8, FORMAT_RGBA8, FORMAT_RGBA4444, FORMAT_RGB565, - FORMAT_RF, //float + FORMAT_RF, // Float FORMAT_RGF, FORMAT_RGBF, FORMAT_RGBAF, - FORMAT_RH, //half float + FORMAT_RH, // Half FORMAT_RGH, FORMAT_RGBH, FORMAT_RGBAH, FORMAT_RGBE9995, - FORMAT_DXT1, //s3tc bc1 - FORMAT_DXT3, //bc2 - FORMAT_DXT5, //bc3 - FORMAT_RGTC_R, - FORMAT_RGTC_RG, - FORMAT_BPTC_RGBA, //btpc bc7 - FORMAT_BPTC_RGBF, //float bc6h - FORMAT_BPTC_RGBFU, //unsigned float bc6hu - FORMAT_ETC, //etc1 - FORMAT_ETC2_R11, //etc2 - FORMAT_ETC2_R11S, //signed, NOT srgb. + FORMAT_DXT1, // BC1 + FORMAT_DXT3, // BC2 + FORMAT_DXT5, // BC3 + FORMAT_RGTC_R, // BC4 + FORMAT_RGTC_RG, // BC5 + FORMAT_BPTC_RGBA, // BC7 + FORMAT_BPTC_RGBF, // BC6 Signed + FORMAT_BPTC_RGBFU, // BC6 Unsigned + FORMAT_ETC, // ETC1 + FORMAT_ETC2_R11, + FORMAT_ETC2_R11S, // Signed, NOT srgb. FORMAT_ETC2_RG11, - FORMAT_ETC2_RG11S, + FORMAT_ETC2_RG11S, // Signed, NOT srgb. FORMAT_ETC2_RGB8, FORMAT_ETC2_RGBA8, FORMAT_ETC2_RGB8A1, - FORMAT_ETC2_RA_AS_RG, //used to make basis universal happy - FORMAT_DXT5_RA_AS_RG, //used to make basis universal happy + FORMAT_ETC2_RA_AS_RG, // ETC2 RGBA with a RA-RG swizzle for normal maps. + FORMAT_DXT5_RA_AS_RG, // BC3 with a RA-RG swizzle for normal maps. FORMAT_ASTC_4x4, FORMAT_ASTC_4x4_HDR, FORMAT_ASTC_8x8, @@ -118,17 +114,18 @@ public: }; static const char *format_names[FORMAT_MAX]; + enum Interpolation { INTERPOLATE_NEAREST, INTERPOLATE_BILINEAR, INTERPOLATE_CUBIC, INTERPOLATE_TRILINEAR, INTERPOLATE_LANCZOS, - /* INTERPOLATE_TRICUBIC, */ - /* INTERPOLATE GAUSS */ + // INTERPOLATE_TRICUBIC, + // INTERPOLATE_GAUSS }; - //this is used for compression + // Used for obtaining optimal compression quality. enum UsedChannels { USED_CHANNELS_L, USED_CHANNELS_LA, @@ -137,13 +134,66 @@ public: USED_CHANNELS_RGB, USED_CHANNELS_RGBA, }; - //some functions provided by something else + // ASTC supports block formats other than 4x4. enum ASTCFormat { ASTC_FORMAT_4x4, ASTC_FORMAT_8x8, }; + enum RoughnessChannel { + ROUGHNESS_CHANNEL_R, + ROUGHNESS_CHANNEL_G, + ROUGHNESS_CHANNEL_B, + ROUGHNESS_CHANNEL_A, + ROUGHNESS_CHANNEL_L, + }; + + enum Image3DValidateError { + VALIDATE_3D_OK, + VALIDATE_3D_ERR_IMAGE_EMPTY, + VALIDATE_3D_ERR_MISSING_IMAGES, + VALIDATE_3D_ERR_EXTRA_IMAGES, + VALIDATE_3D_ERR_IMAGE_SIZE_MISMATCH, + VALIDATE_3D_ERR_IMAGE_FORMAT_MISMATCH, + VALIDATE_3D_ERR_IMAGE_HAS_MIPMAPS, + }; + + enum CompressMode { + COMPRESS_S3TC, + COMPRESS_ETC, + COMPRESS_ETC2, + COMPRESS_BPTC, + COMPRESS_ASTC, + COMPRESS_MAX, + }; + + enum CompressSource { + COMPRESS_SOURCE_GENERIC, + COMPRESS_SOURCE_SRGB, + COMPRESS_SOURCE_NORMAL, + COMPRESS_SOURCE_MAX, + }; + + enum AlphaMode { + ALPHA_NONE, + ALPHA_BIT, + ALPHA_BLEND + }; + + // External saver function pointers. + + static SavePNGFunc save_png_func; + static SaveJPGFunc save_jpg_func; + static SaveEXRFunc save_exr_func; + static SaveWebPFunc save_webp_func; + static SavePNGBufferFunc save_png_buffer_func; + static SaveEXRBufferFunc save_exr_buffer_func; + static SaveJPGBufferFunc save_jpg_buffer_func; + static SaveWebPBufferFunc save_webp_buffer_func; + + // External loader function pointers. + static ImageMemLoadFunc _png_mem_loader_func; static ImageMemLoadFunc _png_mem_unpacker_func; static ImageMemLoadFunc _jpg_mem_loader_func; @@ -153,6 +203,8 @@ public: static ScalableImageMemLoadFunc _svg_scalable_mem_loader_func; static ImageMemLoadFunc _ktx_mem_loader_func; + // External VRAM compression function pointers. + static void (*_image_compress_bc_func)(Image *, UsedChannels p_channels); static void (*_image_compress_bptc_func)(Image *, UsedChannels p_channels); static void (*_image_compress_etc1_func)(Image *); @@ -162,24 +214,26 @@ public: static Error (*_image_compress_bptc_rd_func)(Image *, UsedChannels p_channels); static Error (*_image_compress_bc_rd_func)(Image *, UsedChannels p_channels); + // External VRAM decompression function pointers. + static void (*_image_decompress_bc)(Image *); static void (*_image_decompress_bptc)(Image *); static void (*_image_decompress_etc1)(Image *); static void (*_image_decompress_etc2)(Image *); static void (*_image_decompress_astc)(Image *); + // External packer function pointers. + static Vector<uint8_t> (*webp_lossy_packer)(const Ref<Image> &p_image, float p_quality); static Vector<uint8_t> (*webp_lossless_packer)(const Ref<Image> &p_image); - static Ref<Image> (*webp_unpacker)(const Vector<uint8_t> &p_buffer); static Vector<uint8_t> (*png_packer)(const Ref<Image> &p_image); - static Ref<Image> (*png_unpacker)(const Vector<uint8_t> &p_buffer); static Vector<uint8_t> (*basis_universal_packer)(const Ref<Image> &p_image, UsedChannels p_channels); + + static Ref<Image> (*webp_unpacker)(const Vector<uint8_t> &p_buffer); + static Ref<Image> (*png_unpacker)(const Vector<uint8_t> &p_buffer); static Ref<Image> (*basis_universal_unpacker)(const Vector<uint8_t> &p_buffer); static Ref<Image> (*basis_universal_unpacker_ptr)(const uint8_t *p_data, int p_size); - _FORCE_INLINE_ Color _get_color_at_ofs(const uint8_t *ptr, uint32_t ofs) const; - _FORCE_INLINE_ void _set_color_at_ofs(uint8_t *ptr, uint32_t ofs, const Color &p_color); - protected: static void _bind_methods(); @@ -190,15 +244,12 @@ private: int height = 0; bool mipmaps = false; - void _copy_internals_from(const Image &p_image) { - format = p_image.format; - width = p_image.width; - height = p_image.height; - mipmaps = p_image.mipmaps; - data = p_image.data; - } + void _copy_internals_from(const Image &p_image); + + _FORCE_INLINE_ Color _get_color_at_ofs(const uint8_t *ptr, uint32_t ofs) const; + _FORCE_INLINE_ void _set_color_at_ofs(uint8_t *ptr, uint32_t ofs, const Color &p_color); - _FORCE_INLINE_ void _get_mipmap_offset_and_size(int p_mipmap, int64_t &r_offset, int &r_width, int &r_height) const; //get where the mipmap begins in data + _FORCE_INLINE_ void _get_mipmap_offset_and_size(int p_mipmap, int64_t &r_offset, int &r_width, int &r_height) const; // Get where the mipmap begins in data. static int64_t _get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps = -1, int *r_mm_width = nullptr, int *r_mm_height = nullptr); bool _can_modify(Format p_format) const; @@ -225,52 +276,32 @@ private: static void renormalize_rgbe9995(uint32_t *p_rgb); public: - int get_width() const; ///< Get image width - int get_height() const; ///< Get image height + int get_width() const; + int get_height() const; Size2i get_size() const; bool has_mipmaps() const; int get_mipmap_count() const; - /** - * Convert the image to another format, conversion only to raw byte format - */ + // Convert the image to another format, conversion only to raw byte format. void convert(Format p_new_format); - /** - * Get the current image format. - */ Format get_format() const; - /** - * Get where the mipmap begins in data. - */ + // Get where the mipmap begins in data. int64_t get_mipmap_offset(int p_mipmap) const; void get_mipmap_offset_and_size(int p_mipmap, int64_t &r_ofs, int64_t &r_size) const; void get_mipmap_offset_size_and_dimensions(int p_mipmap, int64_t &r_ofs, int64_t &r_size, int &w, int &h) const; - enum Image3DValidateError { - VALIDATE_3D_OK, - VALIDATE_3D_ERR_IMAGE_EMPTY, - VALIDATE_3D_ERR_MISSING_IMAGES, - VALIDATE_3D_ERR_EXTRA_IMAGES, - VALIDATE_3D_ERR_IMAGE_SIZE_MISMATCH, - VALIDATE_3D_ERR_IMAGE_FORMAT_MISMATCH, - VALIDATE_3D_ERR_IMAGE_HAS_MIPMAPS, - }; - static Image3DValidateError validate_3d_image(Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_images); static String get_3d_image_validation_error_text(Image3DValidateError p_error); - /** - * Resize the image, using the preferred interpolation method. - */ + // Resize the image, using the preferred interpolation method. void resize_to_po2(bool p_square = false, Interpolation p_interpolation = INTERPOLATE_BILINEAR); void resize(int p_width, int p_height, Interpolation p_interpolation = INTERPOLATE_BILINEAR); void shrink_x2(); bool is_size_po2() const; - /** - * Crop the image to a specific size, if larger, then the image is filled by black - */ + + // Crop the image to a specific size, if larger, then the image is filled by black. void crop_from_point(int p_x, int p_y, int p_width, int p_height); void crop(int p_width, int p_height); @@ -280,34 +311,20 @@ public: void flip_x(); void flip_y(); - /** - * Generate a mipmap to an image (creates an image 1/4 the size, with averaging of 4->1) - */ + // Generate a mipmap chain of an image (creates an image 1/4 the size, with averaging of 4->1). Error generate_mipmaps(bool p_renormalize = false); - enum RoughnessChannel { - ROUGHNESS_CHANNEL_R, - ROUGHNESS_CHANNEL_G, - ROUGHNESS_CHANNEL_B, - ROUGHNESS_CHANNEL_A, - ROUGHNESS_CHANNEL_L, - }; - Error generate_mipmap_roughness(RoughnessChannel p_roughness_channel, const Ref<Image> &p_normal_map); void clear_mipmaps(); - void normalize(); //for normal maps + void normalize(); - /** - * Creates new internal image data of a given size and format. Current image will be lost. - */ + // Creates new internal image data of a given size and format. Current image will be lost. void initialize_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format); void initialize_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data); void initialize_data(const char **p_xpm); - /** - * returns true when the image is empty (0,0) in size - */ + // Returns true when the image is empty (0,0) in size. bool is_empty() const; Vector<uint8_t> get_data() const; @@ -327,27 +344,14 @@ public: static Ref<Image> create_from_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data); void set_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data); - /** - * create an empty image - */ - Image() {} - /** - * create an empty image of a specific size and format - */ - Image(int p_width, int p_height, bool p_use_mipmaps, Format p_format); - /** - * import an image of a specific size and format from a pointer - */ - Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const Vector<uint8_t> &p_data); + Image() = default; // Create an empty image. + Image(int p_width, int p_height, bool p_use_mipmaps, Format p_format); // Create an empty image of a specific size and format. + Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const Vector<uint8_t> &p_data); // Import an image of a specific size and format from a byte vector. + Image(const uint8_t *p_mem_png_jpg, int p_len = -1); // Import either a png or jpg from a pointer. + Image(const char **p_xpm); // Import an XPM image. ~Image() {} - enum AlphaMode { - ALPHA_NONE, - ALPHA_BIT, - ALPHA_BLEND - }; - AlphaMode detect_alpha() const; bool is_invisible() const; @@ -362,21 +366,6 @@ public: static int64_t get_image_mipmap_offset(int p_width, int p_height, Format p_format, int p_mipmap); static int64_t get_image_mipmap_offset_and_dimensions(int p_width, int p_height, Format p_format, int p_mipmap, int &r_w, int &r_h); - enum CompressMode { - COMPRESS_S3TC, - COMPRESS_ETC, - COMPRESS_ETC2, - COMPRESS_BPTC, - COMPRESS_ASTC, - COMPRESS_MAX, - }; - enum CompressSource { - COMPRESS_SOURCE_GENERIC, - COMPRESS_SOURCE_SRGB, - COMPRESS_SOURCE_NORMAL, - COMPRESS_SOURCE_MAX, - }; - Error compress(CompressMode p_mode, CompressSource p_source = COMPRESS_SOURCE_GENERIC, ASTCFormat p_astc_format = ASTC_FORMAT_4x4); Error compress_from_channels(CompressMode p_mode, UsedChannels p_channels, ASTCFormat p_astc_format = ASTC_FORMAT_4x4); Error decompress(); @@ -422,9 +411,6 @@ public: void convert_ra_rgba8_to_rg(); void convert_rgba8_to_bgra8(); - Image(const uint8_t *p_mem_png_jpg, int p_len = -1); - Image(const char **p_xpm); - virtual Ref<Resource> duplicate(bool p_subresources = false) const override; UsedChannels detect_used_channels(CompressSource p_source = COMPRESS_SOURCE_GENERIC) const; @@ -443,14 +429,7 @@ public: void set_as_black(); - void copy_internals_from(const Ref<Image> &p_image) { - ERR_FAIL_COND_MSG(p_image.is_null(), "Cannot copy image internals: invalid Image object."); - format = p_image->format; - width = p_image->width; - height = p_image->height; - mipmaps = p_image->mipmaps; - data = p_image->data; - } + void copy_internals_from(const Ref<Image> &p_image); Dictionary compute_image_metrics(const Ref<Image> p_compared_image, bool p_luma_metric = true); }; diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index c4d11b8a32..d9664e7370 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -33,8 +33,6 @@ #include "core/io/resource_loader.h" #include "core/object/ref_counted.h" #include "core/object/script_language.h" -#include "core/os/keyboard.h" -#include "core/string/print_string.h" #include <limits.h> #include <stdio.h> @@ -69,10 +67,31 @@ ObjectID EncodedObjectAsID::get_object_id() const { // For `Variant::ARRAY`. // Occupies bits 16 and 17. #define HEADER_DATA_FIELD_TYPED_ARRAY_MASK (0b11 << 16) -#define HEADER_DATA_FIELD_TYPED_ARRAY_NONE (0b00 << 16) -#define HEADER_DATA_FIELD_TYPED_ARRAY_BUILTIN (0b01 << 16) -#define HEADER_DATA_FIELD_TYPED_ARRAY_CLASS_NAME (0b10 << 16) -#define HEADER_DATA_FIELD_TYPED_ARRAY_SCRIPT (0b11 << 16) +#define HEADER_DATA_FIELD_TYPED_ARRAY_SHIFT 16 + +// For `Variant::DICTIONARY`. +// Occupies bits 16 and 17. +#define HEADER_DATA_FIELD_TYPED_DICTIONARY_KEY_MASK (0b11 << 16) +#define HEADER_DATA_FIELD_TYPED_DICTIONARY_KEY_SHIFT 16 +// Occupies bits 18 and 19. +#define HEADER_DATA_FIELD_TYPED_DICTIONARY_VALUE_MASK (0b11 << 18) +#define HEADER_DATA_FIELD_TYPED_DICTIONARY_VALUE_SHIFT 18 + +enum ContainerTypeKind { + CONTAINER_TYPE_KIND_NONE = 0b00, + CONTAINER_TYPE_KIND_BUILTIN = 0b01, + CONTAINER_TYPE_KIND_CLASS_NAME = 0b10, + CONTAINER_TYPE_KIND_SCRIPT = 0b11, +}; + +struct ContainerType { + Variant::Type builtin_type = Variant::NIL; + StringName class_name; + Ref<Script> script; +}; + +#define GET_CONTAINER_TYPE_KIND(m_header, m_field) \ + ((ContainerTypeKind)(((m_header) & HEADER_DATA_FIELD_##m_field##_MASK) >> HEADER_DATA_FIELD_##m_field##_SHIFT)) static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r_string) { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); @@ -80,7 +99,7 @@ static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r int32_t strlen = decode_uint32(buf); int32_t pad = 0; - // Handle padding + // Handle padding. if (strlen % 4) { pad = 4 - strlen % 4; } @@ -88,7 +107,7 @@ static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r buf += 4; len -= 4; - // Ensure buffer is big enough + // Ensure buffer is big enough. ERR_FAIL_ADD_OF(strlen, pad, ERR_FILE_EOF); ERR_FAIL_COND_V(strlen < 0 || strlen + pad > len, ERR_FILE_EOF); @@ -96,10 +115,10 @@ static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r ERR_FAIL_COND_V(str.parse_utf8((const char *)buf, strlen) != OK, ERR_INVALID_DATA); r_string = str; - // Add padding + // Add padding. strlen += pad; - // Update buffer pos, left data count, and return size + // Update buffer pos, left data count, and return size. buf += strlen; len -= strlen; if (r_len) { @@ -109,6 +128,65 @@ static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r return OK; } +static Error _decode_container_type(const uint8_t *&buf, int &len, int *r_len, bool p_allow_objects, ContainerTypeKind p_type_kind, ContainerType &r_type) { + switch (p_type_kind) { + case CONTAINER_TYPE_KIND_NONE: { + return OK; + } break; + case CONTAINER_TYPE_KIND_BUILTIN: { + ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); + + int32_t bt = decode_uint32(buf); + buf += 4; + len -= 4; + if (r_len) { + (*r_len) += 4; + } + + ERR_FAIL_INDEX_V(bt, Variant::VARIANT_MAX, ERR_INVALID_DATA); + r_type.builtin_type = (Variant::Type)bt; + if (!p_allow_objects && r_type.builtin_type == Variant::OBJECT) { + r_type.class_name = EncodedObjectAsID::get_class_static(); + } + return OK; + } break; + case CONTAINER_TYPE_KIND_CLASS_NAME: { + String str; + Error err = _decode_string(buf, len, r_len, str); + if (err) { + return err; + } + + r_type.builtin_type = Variant::OBJECT; + if (p_allow_objects) { + r_type.class_name = str; + } else { + r_type.class_name = EncodedObjectAsID::get_class_static(); + } + return OK; + } break; + case CONTAINER_TYPE_KIND_SCRIPT: { + String path; + Error err = _decode_string(buf, len, r_len, path); + if (err) { + return err; + } + + r_type.builtin_type = Variant::OBJECT; + if (p_allow_objects) { + ERR_FAIL_COND_V_MSG(path.is_empty() || !path.begins_with("res://") || !ResourceLoader::exists(path, "Script"), ERR_INVALID_DATA, vformat("Invalid script path \"%s\".", path)); + r_type.script = ResourceLoader::load(path, "Script"); + ERR_FAIL_COND_V_MSG(r_type.script.is_null(), ERR_INVALID_DATA, vformat("Can't load script at path \"%s\".", path)); + r_type.class_name = r_type.script->get_instance_base_type(); + } else { + r_type.class_name = EncodedObjectAsID::get_class_static(); + } + return OK; + } break; + } + ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Invalid container type kind."); // Future proofing. +} + Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len, bool p_allow_objects, int p_depth) { ERR_FAIL_COND_V_MSG(p_depth > Variant::MAX_RECURSION_DEPTH, ERR_OUT_OF_MEMORY, "Variant is too deep. Bailing."); const uint8_t *buf = p_buffer; @@ -126,7 +204,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = 4; } - // Note: We cannot use sizeof(real_t) for decoding, in case a different size is encoded. + // NOTE: We cannot use `sizeof(real_t)` for decoding, in case a different size is encoded. // Decoding math types always checks for the encoded size, while encoding always uses compilation setting. // This does lead to some code duplication for decoding, but compatibility is the priority. switch (header & HEADER_TYPE_MASK) { @@ -188,7 +266,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } break; - // math types + // Math types. case Variant::VECTOR2: { Vector2 val; if (header & HEADER_DATA_FLAG_64) { @@ -539,7 +617,8 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int r_variant = val; } break; - // misc types + + // Misc types. case Variant::COLOR: { ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA); Color val; @@ -568,7 +647,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int int32_t strlen = decode_uint32(buf); if (strlen & 0x80000000) { - //new format + // New format. ERR_FAIL_COND_V(len < 12, ERR_INVALID_DATA); Vector<StringName> names; Vector<StringName> subnames; @@ -607,8 +686,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int r_variant = NodePath(names, subnames, np_flags & 1); } else { - //old format, just a string - + // Old format, just a string. ERR_FAIL_V(ERR_INVALID_DATA); } @@ -698,9 +776,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int if (str == "script" && value.get_type() != Variant::NIL) { ERR_FAIL_COND_V_MSG(value.get_type() != Variant::STRING, ERR_INVALID_DATA, "Invalid value for \"script\" property, expected script path as String."); String path = value; - ERR_FAIL_COND_V_MSG(path.is_empty() || !path.begins_with("res://") || !ResourceLoader::exists(path, "Script"), ERR_INVALID_DATA, vformat("Invalid script path: '%s'.", path)); + ERR_FAIL_COND_V_MSG(path.is_empty() || !path.begins_with("res://") || !ResourceLoader::exists(path, "Script"), ERR_INVALID_DATA, vformat("Invalid script path \"%s\".", path)); Ref<Script> script = ResourceLoader::load(path, "Script"); - ERR_FAIL_COND_V_MSG(script.is_null(), ERR_INVALID_DATA, vformat("Can't load script at path: '%s'.", path)); + ERR_FAIL_COND_V_MSG(script.is_null(), ERR_INVALID_DATA, vformat("Can't load script at path \"%s\".", path)); obj->set_script(script); } else { obj->set(str, value); @@ -731,9 +809,30 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int r_variant = Signal(id, StringName(name)); } break; case Variant::DICTIONARY: { + ContainerType key_type; + + { + ContainerTypeKind key_type_kind = GET_CONTAINER_TYPE_KIND(header, TYPED_DICTIONARY_KEY); + Error err = _decode_container_type(buf, len, r_len, p_allow_objects, key_type_kind, key_type); + if (err) { + return err; + } + } + + ContainerType value_type; + + { + ContainerTypeKind value_type_kind = GET_CONTAINER_TYPE_KIND(header, TYPED_DICTIONARY_VALUE); + Error err = _decode_container_type(buf, len, r_len, p_allow_objects, value_type_kind, value_type); + if (err) { + return err; + } + } + ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); + int32_t count = decode_uint32(buf); - // bool shared = count&0x80000000; + //bool shared = count & 0x80000000; count &= 0x7FFFFFFF; buf += 4; @@ -743,7 +842,10 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int (*r_len) += 4; // Size of count number. } - Dictionary d; + Dictionary dict; + if (key_type.builtin_type != Variant::NIL || value_type.builtin_type != Variant::NIL) { + dict.set_typed(key_type.builtin_type, key_type.class_name, key_type.script, value_type.builtin_type, value_type.class_name, value_type.script); + } for (int i = 0; i < count; i++) { Variant key, value; @@ -767,75 +869,27 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int (*r_len) += used; } - d[key] = value; + dict[key] = value; } - r_variant = d; + r_variant = dict; } break; case Variant::ARRAY: { - Variant::Type builtin_type = Variant::VARIANT_MAX; - StringName class_name; - Ref<Script> script; - - switch (header & HEADER_DATA_FIELD_TYPED_ARRAY_MASK) { - case HEADER_DATA_FIELD_TYPED_ARRAY_NONE: - break; // Untyped array. - case HEADER_DATA_FIELD_TYPED_ARRAY_BUILTIN: { - ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); - - int32_t bt = decode_uint32(buf); - buf += 4; - len -= 4; - if (r_len) { - (*r_len) += 4; - } + ContainerType type; - ERR_FAIL_INDEX_V(bt, Variant::VARIANT_MAX, ERR_INVALID_DATA); - builtin_type = (Variant::Type)bt; - if (!p_allow_objects && builtin_type == Variant::OBJECT) { - class_name = EncodedObjectAsID::get_class_static(); - } - } break; - case HEADER_DATA_FIELD_TYPED_ARRAY_CLASS_NAME: { - String str; - Error err = _decode_string(buf, len, r_len, str); - if (err) { - return err; - } - - builtin_type = Variant::OBJECT; - if (p_allow_objects) { - class_name = str; - } else { - class_name = EncodedObjectAsID::get_class_static(); - } - } break; - case HEADER_DATA_FIELD_TYPED_ARRAY_SCRIPT: { - String path; - Error err = _decode_string(buf, len, r_len, path); - if (err) { - return err; - } - - builtin_type = Variant::OBJECT; - if (p_allow_objects) { - ERR_FAIL_COND_V_MSG(path.is_empty() || !path.begins_with("res://") || !ResourceLoader::exists(path, "Script"), ERR_INVALID_DATA, vformat("Invalid script path: '%s'.", path)); - script = ResourceLoader::load(path, "Script"); - ERR_FAIL_COND_V_MSG(script.is_null(), ERR_INVALID_DATA, vformat("Can't load script at path: '%s'.", path)); - class_name = script->get_instance_base_type(); - } else { - class_name = EncodedObjectAsID::get_class_static(); - } - } break; - default: - ERR_FAIL_V(ERR_INVALID_DATA); // Future proofing. + { + ContainerTypeKind type_kind = GET_CONTAINER_TYPE_KIND(header, TYPED_ARRAY); + Error err = _decode_container_type(buf, len, r_len, p_allow_objects, type_kind, type); + if (err) { + return err; + } } ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); int32_t count = decode_uint32(buf); - // bool shared = count&0x80000000; + //bool shared = count & 0x80000000; count &= 0x7FFFFFFF; buf += 4; @@ -845,29 +899,29 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int (*r_len) += 4; // Size of count number. } - Array varr; - if (builtin_type != Variant::VARIANT_MAX) { - varr.set_typed(builtin_type, class_name, script); + Array array; + if (type.builtin_type != Variant::NIL) { + array.set_typed(type.builtin_type, type.class_name, type.script); } for (int i = 0; i < count; i++) { int used = 0; - Variant v; - Error err = decode_variant(v, buf, len, &used, p_allow_objects, p_depth + 1); + Variant elem; + Error err = decode_variant(elem, buf, len, &used, p_allow_objects, p_depth + 1); ERR_FAIL_COND_V_MSG(err != OK, err, "Error when trying to decode Variant."); buf += used; len -= used; - varr.push_back(v); + array.push_back(elem); if (r_len) { (*r_len) += used; } } - r_variant = varr; + r_variant = array; } break; - // arrays + // Packed arrays. case Variant::PACKED_BYTE_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); int32_t count = decode_uint32(buf); @@ -906,7 +960,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int Vector<int32_t> data; if (count) { - //const int*rbuf=(const int*)buf; + //const int *rbuf = (const int *)buf; data.resize(count); int32_t *w = data.ptrw(); for (int32_t i = 0; i < count; i++) { @@ -930,7 +984,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int Vector<int64_t> data; if (count) { - //const int*rbuf=(const int*)buf; + //const int *rbuf = (const int *)buf; data.resize(count); int64_t *w = data.ptrw(); for (int64_t i = 0; i < count; i++) { @@ -954,7 +1008,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int Vector<float> data; if (count) { - //const float*rbuf=(const float*)buf; + //const float *rbuf = (const float *)buf; data.resize(count); float *w = data.ptrw(); for (int32_t i = 0; i < count; i++) { @@ -1265,13 +1319,50 @@ static void _encode_string(const String &p_string, uint8_t *&buf, int &r_len) { r_len += 4 + utf8.length(); while (r_len % 4) { - r_len++; //pad + r_len++; // Pad. if (buf) { *(buf++) = 0; } } } +static void _encode_container_type_header(const ContainerType &p_type, uint32_t &header, uint32_t p_shift, bool p_full_objects) { + if (p_type.builtin_type != Variant::NIL) { + if (p_type.script.is_valid()) { + header |= (p_full_objects ? CONTAINER_TYPE_KIND_SCRIPT : CONTAINER_TYPE_KIND_CLASS_NAME) << p_shift; + } else if (p_type.class_name != StringName()) { + header |= CONTAINER_TYPE_KIND_CLASS_NAME << p_shift; + } else { + // No need to check `p_full_objects` since `class_name` should be non-empty for `builtin_type == Variant::OBJECT`. + header |= CONTAINER_TYPE_KIND_BUILTIN << p_shift; + } + } +} + +static Error _encode_container_type(const ContainerType &p_type, uint8_t *&buf, int &r_len, bool p_full_objects) { + if (p_type.builtin_type != Variant::NIL) { + if (p_type.script.is_valid()) { + if (p_full_objects) { + String path = p_type.script->get_path(); + ERR_FAIL_COND_V_MSG(path.is_empty() || !path.begins_with("res://"), ERR_UNAVAILABLE, "Failed to encode a path to a custom script for a container type."); + _encode_string(path, buf, r_len); + } else { + _encode_string(EncodedObjectAsID::get_class_static(), buf, r_len); + } + } else if (p_type.class_name != StringName()) { + _encode_string(p_full_objects ? p_type.class_name.operator String() : EncodedObjectAsID::get_class_static(), buf, r_len); + } else { + // No need to check `p_full_objects` since `class_name` should be non-empty for `builtin_type == Variant::OBJECT`. + if (buf) { + encode_uint32(p_type.builtin_type, buf); + buf += 4; + } + r_len += 4; + } + } + return OK; +} + Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects, int p_depth) { ERR_FAIL_COND_V_MSG(p_depth > Variant::MAX_RECURSION_DEPTH, ERR_OUT_OF_MEMORY, "Potential infinite recursion detected. Bailing."); uint8_t *buf = r_buffer; @@ -1310,20 +1401,32 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo header |= HEADER_DATA_FLAG_OBJECT_AS_ID; } } break; + case Variant::DICTIONARY: { + Dictionary dict = p_variant; + + ContainerType key_type; + key_type.builtin_type = (Variant::Type)dict.get_typed_key_builtin(); + key_type.class_name = dict.get_typed_key_class_name(); + key_type.script = dict.get_typed_key_script(); + + _encode_container_type_header(key_type, header, HEADER_DATA_FIELD_TYPED_DICTIONARY_KEY_SHIFT, p_full_objects); + + ContainerType value_type; + value_type.builtin_type = (Variant::Type)dict.get_typed_value_builtin(); + value_type.class_name = dict.get_typed_value_class_name(); + value_type.script = dict.get_typed_value_script(); + + _encode_container_type_header(value_type, header, HEADER_DATA_FIELD_TYPED_DICTIONARY_VALUE_SHIFT, p_full_objects); + } break; case Variant::ARRAY: { Array array = p_variant; - if (array.is_typed()) { - Ref<Script> script = array.get_typed_script(); - if (script.is_valid()) { - header |= p_full_objects ? HEADER_DATA_FIELD_TYPED_ARRAY_SCRIPT : HEADER_DATA_FIELD_TYPED_ARRAY_CLASS_NAME; - } else if (array.get_typed_class_name() != StringName()) { - header |= HEADER_DATA_FIELD_TYPED_ARRAY_CLASS_NAME; - } else { - // No need to check `p_full_objects` since for `Variant::OBJECT` - // `array.get_typed_class_name()` should be non-empty. - header |= HEADER_DATA_FIELD_TYPED_ARRAY_BUILTIN; - } - } + + ContainerType type; + type.builtin_type = (Variant::Type)array.get_typed_builtin(); + type.class_name = array.get_typed_class_name(); + type.script = array.get_typed_script(); + + _encode_container_type_header(type, header, HEADER_DATA_FIELD_TYPED_ARRAY_SHIFT, p_full_objects); } break; #ifdef REAL_T_IS_DOUBLE case Variant::VECTOR2: @@ -1344,7 +1447,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } break; #endif // REAL_T_IS_DOUBLE default: { - } // nothing to do at this stage + // Nothing to do at this stage. + } break; } if (buf) { @@ -1355,7 +1459,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo switch (p_variant.get_type()) { case Variant::NIL: { - //nothing to do + // Nothing to do. } break; case Variant::BOOL: { if (buf) { @@ -1367,7 +1471,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } break; case Variant::INT: { if (header & HEADER_DATA_FLAG_64) { - //64 bits + // 64 bits. if (buf) { encode_uint64(p_variant.operator int64_t(), buf); } @@ -1401,7 +1505,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo case Variant::NODE_PATH: { NodePath np = p_variant; if (buf) { - encode_uint32(uint32_t(np.get_name_count()) | 0x80000000, buf); //for compatibility with the old format + encode_uint32(uint32_t(np.get_name_count()) | 0x80000000, buf); // For compatibility with the old format. encode_uint32(np.get_subname_count(), buf + 4); uint32_t np_flags = 0; if (np.is_absolute()) { @@ -1451,7 +1555,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } break; - // math types + // Math types. case Variant::VECTOR2: { if (buf) { Vector2 v2 = p_variant; @@ -1635,7 +1739,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } break; - // misc types + // Misc types. case Variant::COLOR: { if (buf) { Color c = p_variant; @@ -1746,29 +1850,53 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 8; } break; case Variant::DICTIONARY: { - Dictionary d = p_variant; + Dictionary dict = p_variant; + + { + ContainerType key_type; + key_type.builtin_type = (Variant::Type)dict.get_typed_key_builtin(); + key_type.class_name = dict.get_typed_key_class_name(); + key_type.script = dict.get_typed_key_script(); + + Error err = _encode_container_type(key_type, buf, r_len, p_full_objects); + if (err) { + return err; + } + } + + { + ContainerType value_type; + value_type.builtin_type = (Variant::Type)dict.get_typed_value_builtin(); + value_type.class_name = dict.get_typed_value_class_name(); + value_type.script = dict.get_typed_value_script(); + + Error err = _encode_container_type(value_type, buf, r_len, p_full_objects); + if (err) { + return err; + } + } if (buf) { - encode_uint32(uint32_t(d.size()), buf); + encode_uint32(uint32_t(dict.size()), buf); buf += 4; } r_len += 4; List<Variant> keys; - d.get_key_list(&keys); + dict.get_key_list(&keys); - for (const Variant &E : keys) { + for (const Variant &key : keys) { int len; - Error err = encode_variant(E, buf, len, p_full_objects, p_depth + 1); + Error err = encode_variant(key, buf, len, p_full_objects, p_depth + 1); ERR_FAIL_COND_V(err, err); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; if (buf) { buf += len; } - Variant *v = d.getptr(E); - ERR_FAIL_NULL_V(v, ERR_BUG); - err = encode_variant(*v, buf, len, p_full_objects, p_depth + 1); + Variant *value = dict.getptr(key); + ERR_FAIL_NULL_V(value, ERR_BUG); + err = encode_variant(*value, buf, len, p_full_objects, p_depth + 1); ERR_FAIL_COND_V(err, err); ERR_FAIL_COND_V(len % 4, ERR_BUG); r_len += len; @@ -1781,27 +1909,15 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo case Variant::ARRAY: { Array array = p_variant; - if (array.is_typed()) { - Variant variant = array.get_typed_script(); - Ref<Script> script = variant; - if (script.is_valid()) { - if (p_full_objects) { - String path = script->get_path(); - ERR_FAIL_COND_V_MSG(path.is_empty() || !path.begins_with("res://"), ERR_UNAVAILABLE, "Failed to encode a path to a custom script for an array type."); - _encode_string(path, buf, r_len); - } else { - _encode_string(EncodedObjectAsID::get_class_static(), buf, r_len); - } - } else if (array.get_typed_class_name() != StringName()) { - _encode_string(p_full_objects ? array.get_typed_class_name().operator String() : EncodedObjectAsID::get_class_static(), buf, r_len); - } else { - // No need to check `p_full_objects` since for `Variant::OBJECT` - // `array.get_typed_class_name()` should be non-empty. - if (buf) { - encode_uint32(array.get_typed_builtin(), buf); - buf += 4; - } - r_len += 4; + { + ContainerType type; + type.builtin_type = (Variant::Type)array.get_typed_builtin(); + type.class_name = array.get_typed_class_name(); + type.script = array.get_typed_script(); + + Error err = _encode_container_type(type, buf, r_len, p_full_objects); + if (err) { + return err; } } @@ -1811,9 +1927,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } r_len += 4; - for (const Variant &var : array) { + for (const Variant &elem : array) { int len; - Error err = encode_variant(var, buf, len, p_full_objects, p_depth + 1); + Error err = encode_variant(elem, buf, len, p_full_objects, p_depth + 1); ERR_FAIL_COND_V(err, err); ERR_FAIL_COND_V(len % 4, ERR_BUG); if (buf) { @@ -1823,7 +1939,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } } break; - // arrays + + // Packed arrays. case Variant::PACKED_BYTE_ARRAY: { Vector<uint8_t> data = p_variant; int datalen = data.size(); @@ -1939,7 +2056,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 4 + utf8.length() + 1; while (r_len % 4) { - r_len++; //pad + r_len++; // Pad. if (buf) { *(buf++) = 0; } @@ -2057,9 +2174,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo } Vector<float> vector3_to_float32_array(const Vector3 *vecs, size_t count) { - // We always allocate a new array, and we don't memcpy. - // We also don't consider returning a pointer to the passed vectors when sizeof(real_t) == 4. - // One reason is that we could decide to put a 4th component in Vector3 for SIMD/mobile performance, + // We always allocate a new array, and we don't `memcpy()`. + // We also don't consider returning a pointer to the passed vectors when `sizeof(real_t) == 4`. + // One reason is that we could decide to put a 4th component in `Vector3` for SIMD/mobile performance, // which would cause trouble with these optimizations. Vector<float> floats; if (count == 0) { diff --git a/core/io/net_socket.h b/core/io/net_socket.h index 120ad5e85b..c12bab622a 100644 --- a/core/io/net_socket.h +++ b/core/io/net_socket.h @@ -76,6 +76,8 @@ public: virtual void set_reuse_address_enabled(bool p_enabled) = 0; virtual Error join_multicast_group(const IPAddress &p_multi_address, const String &p_if_name) = 0; virtual Error leave_multicast_group(const IPAddress &p_multi_address, const String &p_if_name) = 0; + + virtual ~NetSocket() {} }; #endif // NET_SOCKET_H diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp index fae3de2a98..08e5353174 100644 --- a/core/io/packet_peer_udp.cpp +++ b/core/io/packet_peer_udp.cpp @@ -105,6 +105,19 @@ Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { return ERR_UNAVAILABLE; } +/* Bogus GCC warning here: + * In member function 'int RingBuffer<T>::read(T*, int, bool) [with T = unsigned char]', + * inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:112:9, + * inlined from 'virtual Error PacketPeerUDP::get_packet(const uint8_t**, int&)' at core/io/packet_peer_udp.cpp:99:7: + * Error: ./core/ring_buffer.h:68:46: error: writing 1 byte into a region of size 0 [-Werror=stringop-overflow=] + * 68 | p_buf[dst++] = read[pos + i]; + * | ~~~~~~~~~~~~~^~~~~~~ + */ +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic warning "-Wstringop-overflow=0" +#endif + uint32_t size = 0; uint8_t ipv6[16] = {}; rb.read(ipv6, 16, true); @@ -115,6 +128,11 @@ Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { --queue_count; *r_buffer = packet_buffer; r_buffer_size = size; + +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + return OK; } diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp index 8ccf74261f..c832ef5700 100644 --- a/core/io/pck_packer.cpp +++ b/core/io/pck_packer.cpp @@ -48,7 +48,8 @@ static int _get_pad(int p_alignment, int p_n) { void PCKPacker::_bind_methods() { ClassDB::bind_method(D_METHOD("pck_start", "pck_path", "alignment", "key", "encrypt_directory"), &PCKPacker::pck_start, DEFVAL(32), DEFVAL("0000000000000000000000000000000000000000000000000000000000000000"), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("add_file", "pck_path", "source_path", "encrypt"), &PCKPacker::add_file, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("add_file", "target_path", "source_path", "encrypt"), &PCKPacker::add_file, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("add_file_removal", "target_path"), &PCKPacker::add_file_removal); ClassDB::bind_method(D_METHOD("flush", "verbose"), &PCKPacker::flush, DEFVAL(false)); } @@ -106,23 +107,42 @@ Error PCKPacker::pck_start(const String &p_pck_path, int p_alignment, const Stri return OK; } -Error PCKPacker::add_file(const String &p_pck_path, const String &p_src, bool p_encrypt) { +Error PCKPacker::add_file_removal(const String &p_target_path) { ERR_FAIL_COND_V_MSG(file.is_null(), ERR_INVALID_PARAMETER, "File must be opened before use."); - Ref<FileAccess> f = FileAccess::open(p_src, FileAccess::READ); + File pf; + // Simplify path here and on every 'files' access so that paths that have extra '/' + // symbols or 'res://' in them still match the MD5 hash for the saved path. + pf.path = p_target_path.simplify_path().trim_prefix("res://"); + pf.ofs = ofs; + pf.size = 0; + pf.removal = true; + + pf.md5.resize(16); + pf.md5.fill(0); + + files.push_back(pf); + + return OK; +} + +Error PCKPacker::add_file(const String &p_target_path, const String &p_source_path, bool p_encrypt) { + ERR_FAIL_COND_V_MSG(file.is_null(), ERR_INVALID_PARAMETER, "File must be opened before use."); + + Ref<FileAccess> f = FileAccess::open(p_source_path, FileAccess::READ); if (f.is_null()) { return ERR_FILE_CANT_OPEN; } File pf; // Simplify path here and on every 'files' access so that paths that have extra '/' - // symbols in them still match to the MD5 hash for the saved path. - pf.path = p_pck_path.simplify_path(); - pf.src_path = p_src; + // symbols or 'res://' in them still match the MD5 hash for the saved path. + pf.path = p_target_path.simplify_path().trim_prefix("res://"); + pf.src_path = p_source_path; pf.ofs = ofs; pf.size = f->get_length(); - Vector<uint8_t> data = FileAccess::get_file_as_bytes(p_src); + Vector<uint8_t> data = FileAccess::get_file_as_bytes(p_source_path); { unsigned char hash[16]; CryptoCore::md5(data.ptr(), data.size(), hash); @@ -195,6 +215,9 @@ Error PCKPacker::flush(bool p_verbose) { if (files[i].encrypted) { flags |= PACK_FILE_ENCRYPTED; } + if (files[i].removal) { + flags |= PACK_FILE_REMOVAL; + } fhead->store_32(flags); } @@ -218,6 +241,10 @@ Error PCKPacker::flush(bool p_verbose) { int count = 0; for (int i = 0; i < files.size(); i++) { + if (files[i].removal) { + continue; + } + Ref<FileAccess> src = FileAccess::open(files[i].src_path, FileAccess::READ); uint64_t to_write = files[i].size; diff --git a/core/io/pck_packer.h b/core/io/pck_packer.h index 5aac833532..043a1dbdb8 100644 --- a/core/io/pck_packer.h +++ b/core/io/pck_packer.h @@ -53,13 +53,15 @@ class PCKPacker : public RefCounted { uint64_t ofs = 0; uint64_t size = 0; bool encrypted = false; + bool removal = false; Vector<uint8_t> md5; }; Vector<File> files; public: Error pck_start(const String &p_pck_path, int p_alignment = 32, const String &p_key = "0000000000000000000000000000000000000000000000000000000000000000", bool p_encrypt_directory = false); - Error add_file(const String &p_pck_path, const String &p_src, bool p_encrypt = false); + Error add_file(const String &p_target_path, const String &p_source_path, bool p_encrypt = false); + Error add_file_removal(const String &p_target_path); Error flush(bool p_verbose = false); PCKPacker() {} diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index e6136603d4..ed11f96d03 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -1577,6 +1577,10 @@ ResourceUID::ID ResourceFormatLoaderBinary::get_resource_uid(const String &p_pat return loader.uid; } +bool ResourceFormatLoaderBinary::has_custom_uid_support() const { + return true; +} + /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 222e633e58..ec8d7ead5d 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -118,6 +118,7 @@ public: virtual String get_resource_script_class(const String &p_path) const override; virtual void get_classes_used(const String &p_path, HashSet<StringName> *r_classes) override; virtual ResourceUID::ID get_resource_uid(const String &p_path) const override; + virtual bool has_custom_uid_support() const override; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false) override; virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map) override; }; diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index e603f9dfde..b7a14f2b88 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -387,6 +387,10 @@ ResourceUID::ID ResourceFormatImporter::get_resource_uid(const String &p_path) c return pat.uid; } +bool ResourceFormatImporter::has_custom_uid_support() const { + return true; +} + Error ResourceFormatImporter::get_resource_import_info(const String &p_path, StringName &r_type, ResourceUID::ID &r_uid, String &r_import_group_file) const { PathAndType pat; Error err = _get_path_and_type(p_path, pat); diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index 3ca8f7c05d..c3d3c4b67e 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -70,6 +70,7 @@ public: virtual bool handles_type(const String &p_type) const override; virtual String get_resource_type(const String &p_path) const override; virtual ResourceUID::ID get_resource_uid(const String &p_path) const override; + virtual bool has_custom_uid_support() const override; virtual Variant get_resource_metadata(const String &p_path) const; virtual bool is_import_valid(const String &p_path) const override; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false) override; @@ -147,7 +148,7 @@ public: virtual void handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const {} virtual String get_option_group_file() const { return String(); } - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) = 0; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) = 0; virtual bool can_import_threaded() const { return false; } virtual void import_threaded_begin() {} virtual void import_threaded_end() {} diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 59de2879e2..3fea697d0b 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "core/core_bind.h" +#include "core/io/dir_access.h" #include "core/io/file_access.h" #include "core/io/resource_importer.h" #include "core/object/script_language.h" @@ -40,6 +41,7 @@ #include "core/os/safe_binary_mutex.h" #include "core/string/print_string.h" #include "core/string/translation_server.h" +#include "core/templates/rb_set.h" #include "core/variant/variant_parser.h" #include "servers/rendering_server.h" @@ -112,10 +114,21 @@ String ResourceFormatLoader::get_resource_script_class(const String &p_path) con ResourceUID::ID ResourceFormatLoader::get_resource_uid(const String &p_path) const { int64_t uid = ResourceUID::INVALID_ID; - GDVIRTUAL_CALL(_get_resource_uid, p_path, uid); + if (has_custom_uid_support()) { + GDVIRTUAL_CALL(_get_resource_uid, p_path, uid); + } else { + Ref<FileAccess> file = FileAccess::open(p_path + ".uid", FileAccess::READ); + if (file.is_valid()) { + uid = ResourceUID::get_singleton()->text_to_id(file->get_line()); + } + } return uid; } +bool ResourceFormatLoader::has_custom_uid_support() const { + return GDVIRTUAL_IS_OVERRIDDEN(_get_resource_uid); +} + void ResourceFormatLoader::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const { if (p_type.is_empty() || handles_type(p_type)) { get_recognized_extensions(p_extensions); @@ -1159,6 +1172,21 @@ ResourceUID::ID ResourceLoader::get_resource_uid(const String &p_path) { return ResourceUID::INVALID_ID; } +bool ResourceLoader::has_custom_uid_support(const String &p_path) { + String local_path = _validate_local_path(p_path); + + for (int i = 0; i < loader_count; i++) { + if (!loader[i]->recognize_path(local_path)) { + continue; + } + if (loader[i]->has_custom_uid_support()) { + return true; + } + } + + return false; +} + String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_remapped) { String new_path = p_path; @@ -1448,6 +1476,60 @@ bool ResourceLoader::is_cleaning_tasks() { return cleaning_tasks; } +Vector<String> ResourceLoader::list_directory(const String &p_directory) { + RBSet<String> files_found; + Ref<DirAccess> dir = DirAccess::open(p_directory); + if (dir.is_null()) { + return Vector<String>(); + } + + Error err = dir->list_dir_begin(); + if (err != OK) { + return Vector<String>(); + } + + String d = dir->get_next(); + while (!d.is_empty()) { + bool recognized = false; + if (dir->current_is_dir()) { + if (d != "." && d != "..") { + d += "/"; + recognized = true; + } + } else { + if (d.ends_with(".import") || d.ends_with(".remap") || d.ends_with(".uid")) { + d = d.substr(0, d.rfind(".")); + } + + if (d.ends_with(".gdc")) { + d = d.substr(0, d.rfind(".")); + d += ".gd"; + } + + const String full_path = p_directory.path_join(d); + // Try all loaders and pick the first match for the type hint. + for (int i = 0; i < loader_count; i++) { + if (loader[i]->recognize_path(full_path)) { + recognized = true; + break; + } + } + } + + if (recognized) { + files_found.insert(d); + } + d = dir->get_next(); + } + + Vector<String> ret; + for (const String &f : files_found) { + ret.push_back(f); + } + + return ret; +} + void ResourceLoader::initialize() {} void ResourceLoader::finalize() {} diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 0d802ed1f4..ebd6024033 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -81,6 +81,7 @@ public: virtual String get_resource_type(const String &p_path) const; virtual String get_resource_script_class(const String &p_path) const; virtual ResourceUID::ID get_resource_uid(const String &p_path) const; + virtual bool has_custom_uid_support() const; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map); virtual bool is_import_valid(const String &p_path) const { return true; } @@ -238,6 +239,7 @@ public: static String get_resource_type(const String &p_path); static String get_resource_script_class(const String &p_path); static ResourceUID::ID get_resource_uid(const String &p_path); + static bool has_custom_uid_support(const String &p_path); static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false); static Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map); static bool is_import_valid(const String &p_path); @@ -302,6 +304,8 @@ public: static bool is_cleaning_tasks(); + static Vector<String> list_directory(const String &p_directory); + static void initialize(); static void finalize(); }; diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp index c49e15a3a0..3f1c468fb3 100644 --- a/core/io/stream_peer.cpp +++ b/core/io/stream_peer.cpp @@ -223,13 +223,13 @@ void StreamPeer::put_var(const Variant &p_variant, bool p_full_objects) { } uint8_t StreamPeer::get_u8() { - uint8_t buf[1]; + uint8_t buf[1] = {}; get_data(buf, 1); return buf[0]; } int8_t StreamPeer::get_8() { - uint8_t buf[1]; + uint8_t buf[1] = {}; get_data(buf, 1); return buf[0]; } diff --git a/core/io/tcp_server.cpp b/core/io/tcp_server.cpp index f2b3d5e56a..d69d1f1b29 100644 --- a/core/io/tcp_server.cpp +++ b/core/io/tcp_server.cpp @@ -112,7 +112,7 @@ Ref<StreamPeerTCP> TCPServer::take_connection() { return conn; } - conn = Ref<StreamPeerTCP>(memnew(StreamPeerTCP)); + conn.instantiate(); conn->accept_socket(ns, ip, port); return conn; } diff --git a/core/os/os.h b/core/os/os.h index 4bb177eb77..ffdb905aba 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -94,7 +94,15 @@ public: enum RenderThreadMode { RENDER_THREAD_UNSAFE, RENDER_THREAD_SAFE, - RENDER_SEPARATE_THREAD + RENDER_SEPARATE_THREAD, + }; + + enum StdHandleType { + STD_HANDLE_INVALID, + STD_HANDLE_CONSOLE, + STD_HANDLE_FILE, + STD_HANDLE_PIPE, + STD_HANDLE_UNKNOWN, }; protected: @@ -146,7 +154,12 @@ public: void print_rich(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3; void printerr(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3; - virtual String get_stdin_string() = 0; + virtual String get_stdin_string(int64_t p_buffer_size = 1024) = 0; + virtual PackedByteArray get_stdin_buffer(int64_t p_buffer_size = 1024) = 0; + + virtual StdHandleType get_stdin_type() const { return STD_HANDLE_UNKNOWN; } + virtual StdHandleType get_stdout_type() const { return STD_HANDLE_UNKNOWN; } + virtual StdHandleType get_stderr_type() const { return STD_HANDLE_UNKNOWN; } virtual Error get_entropy(uint8_t *r_buffer, int p_bytes) = 0; // Should return cryptographically-safe random bytes. virtual String get_system_ca_certificates() { return ""; } // Concatenated certificates in PEM format. diff --git a/core/string/translation_domain.cpp b/core/string/translation_domain.cpp index cf6689efff..1ff8dcd752 100644 --- a/core/string/translation_domain.cpp +++ b/core/string/translation_domain.cpp @@ -247,7 +247,10 @@ PackedStringArray TranslationDomain::get_loaded_locales() const { PackedStringArray locales; for (const Ref<Translation> &E : translations) { ERR_CONTINUE(E.is_null()); - locales.push_back(E->get_locale()); + const String &locale = E->get_locale(); + if (!locales.has(locale)) { + locales.push_back(locale); + } } return locales; } diff --git a/core/string/translation_server.cpp b/core/string/translation_server.cpp index 92b473b61f..31c221dad7 100644 --- a/core/string/translation_server.cpp +++ b/core/string/translation_server.cpp @@ -118,36 +118,45 @@ void TranslationServer::init_locale_info() { } } -String TranslationServer::standardize_locale(const String &p_locale) const { - return _standardize_locale(p_locale, false); +TranslationServer::Locale::operator String() const { + String out = language; + if (!script.is_empty()) { + out = out + "_" + script; + } + if (!country.is_empty()) { + out = out + "_" + country; + } + if (!variant.is_empty()) { + out = out + "_" + variant; + } + return out; } -String TranslationServer::_standardize_locale(const String &p_locale, bool p_add_defaults) const { +TranslationServer::Locale::Locale(const TranslationServer &p_server, const String &p_locale, bool p_add_defaults) { // Replaces '-' with '_' for macOS style locales. String univ_locale = p_locale.replace("-", "_"); // Extract locale elements. - String lang_name, script_name, country_name, variant_name; Vector<String> locale_elements = univ_locale.get_slice("@", 0).split("_"); - lang_name = locale_elements[0]; + language = locale_elements[0]; if (locale_elements.size() >= 2) { if (locale_elements[1].length() == 4 && is_ascii_upper_case(locale_elements[1][0]) && is_ascii_lower_case(locale_elements[1][1]) && is_ascii_lower_case(locale_elements[1][2]) && is_ascii_lower_case(locale_elements[1][3])) { - script_name = locale_elements[1]; + script = locale_elements[1]; } if (locale_elements[1].length() == 2 && is_ascii_upper_case(locale_elements[1][0]) && is_ascii_upper_case(locale_elements[1][1])) { - country_name = locale_elements[1]; + country = locale_elements[1]; } } if (locale_elements.size() >= 3) { if (locale_elements[2].length() == 2 && is_ascii_upper_case(locale_elements[2][0]) && is_ascii_upper_case(locale_elements[2][1])) { - country_name = locale_elements[2]; - } else if (variant_map.has(locale_elements[2].to_lower()) && variant_map[locale_elements[2].to_lower()] == lang_name) { - variant_name = locale_elements[2].to_lower(); + country = locale_elements[2]; + } else if (p_server.variant_map.has(locale_elements[2].to_lower()) && p_server.variant_map[locale_elements[2].to_lower()] == language) { + variant = locale_elements[2].to_lower(); } } if (locale_elements.size() >= 4) { - if (variant_map.has(locale_elements[3].to_lower()) && variant_map[locale_elements[3].to_lower()] == lang_name) { - variant_name = locale_elements[3].to_lower(); + if (p_server.variant_map.has(locale_elements[3].to_lower()) && p_server.variant_map[locale_elements[3].to_lower()] == language) { + variant = locale_elements[3].to_lower(); } } @@ -155,71 +164,62 @@ String TranslationServer::_standardize_locale(const String &p_locale, bool p_add Vector<String> script_extra = univ_locale.get_slice("@", 1).split(";"); for (int i = 0; i < script_extra.size(); i++) { if (script_extra[i].to_lower() == "cyrillic") { - script_name = "Cyrl"; + script = "Cyrl"; break; } else if (script_extra[i].to_lower() == "latin") { - script_name = "Latn"; + script = "Latn"; break; } else if (script_extra[i].to_lower() == "devanagari") { - script_name = "Deva"; + script = "Deva"; break; - } else if (variant_map.has(script_extra[i].to_lower()) && variant_map[script_extra[i].to_lower()] == lang_name) { - variant_name = script_extra[i].to_lower(); + } else if (p_server.variant_map.has(script_extra[i].to_lower()) && p_server.variant_map[script_extra[i].to_lower()] == language) { + variant = script_extra[i].to_lower(); } } // Handles known non-ISO language names used e.g. on Windows. - if (locale_rename_map.has(lang_name)) { - lang_name = locale_rename_map[lang_name]; + if (p_server.locale_rename_map.has(language)) { + language = p_server.locale_rename_map[language]; } // Handle country renames. - if (country_rename_map.has(country_name)) { - country_name = country_rename_map[country_name]; + if (p_server.country_rename_map.has(country)) { + country = p_server.country_rename_map[country]; } // Remove unsupported script codes. - if (!script_map.has(script_name)) { - script_name = ""; + if (!p_server.script_map.has(script)) { + script = ""; } // Add script code base on language and country codes for some ambiguous cases. if (p_add_defaults) { - if (script_name.is_empty()) { - for (int i = 0; i < locale_script_info.size(); i++) { - const LocaleScriptInfo &info = locale_script_info[i]; - if (info.name == lang_name) { - if (country_name.is_empty() || info.supported_countries.has(country_name)) { - script_name = info.script; + if (script.is_empty()) { + for (int i = 0; i < p_server.locale_script_info.size(); i++) { + const LocaleScriptInfo &info = p_server.locale_script_info[i]; + if (info.name == language) { + if (country.is_empty() || info.supported_countries.has(country)) { + script = info.script; break; } } } } - if (!script_name.is_empty() && country_name.is_empty()) { + if (!script.is_empty() && country.is_empty()) { // Add conntry code based on script for some ambiguous cases. - for (int i = 0; i < locale_script_info.size(); i++) { - const LocaleScriptInfo &info = locale_script_info[i]; - if (info.name == lang_name && info.script == script_name) { - country_name = info.default_country; + for (int i = 0; i < p_server.locale_script_info.size(); i++) { + const LocaleScriptInfo &info = p_server.locale_script_info[i]; + if (info.name == language && info.script == script) { + country = info.default_country; break; } } } } +} - // Combine results. - String out = lang_name; - if (!script_name.is_empty()) { - out = out + "_" + script_name; - } - if (!country_name.is_empty()) { - out = out + "_" + country_name; - } - if (!variant_name.is_empty()) { - out = out + "_" + variant_name; - } - return out; +String TranslationServer::standardize_locale(const String &p_locale) const { + return Locale(*this, p_locale, false).operator String(); } int TranslationServer::compare_locales(const String &p_locale_a, const String &p_locale_b) const { @@ -234,8 +234,8 @@ int TranslationServer::compare_locales(const String &p_locale_a, const String &p return *cached_result; } - String locale_a = _standardize_locale(p_locale_a, true); - String locale_b = _standardize_locale(p_locale_b, true); + Locale locale_a = Locale(*this, p_locale_a, true); + Locale locale_b = Locale(*this, p_locale_b, true); if (locale_a == locale_b) { // Exact match. @@ -243,26 +243,41 @@ int TranslationServer::compare_locales(const String &p_locale_a, const String &p return 10; } - Vector<String> locale_a_elements = locale_a.split("_"); - Vector<String> locale_b_elements = locale_b.split("_"); - if (locale_a_elements[0] != locale_b_elements[0]) { + if (locale_a.language != locale_b.language) { // No match. locale_compare_cache.insert(cache_key, 0); return 0; } - // Matching language, both locales have extra parts. - // Return number of matching elements. - int matching_elements = 1; - for (int i = 1; i < locale_a_elements.size(); i++) { - for (int j = 1; j < locale_b_elements.size(); j++) { - if (locale_a_elements[i] == locale_b_elements[j]) { - matching_elements++; - } + // Matching language, both locales have extra parts. Compare the + // remaining elements. If both elements are non-empty, check the + // match to increase or decrease the score. If either element or + // both are empty, leave the score as is. + int score = 5; + if (!locale_a.script.is_empty() && !locale_b.script.is_empty()) { + if (locale_a.script == locale_b.script) { + score++; + } else { + score--; } } - locale_compare_cache.insert(cache_key, matching_elements); - return matching_elements; + if (!locale_a.country.is_empty() && !locale_b.country.is_empty()) { + if (locale_a.country == locale_b.country) { + score++; + } else { + score--; + } + } + if (!locale_a.variant.is_empty() && !locale_b.variant.is_empty()) { + if (locale_a.variant == locale_b.variant) { + score++; + } else { + score--; + } + } + + locale_compare_cache.insert(cache_key, score); + return score; } String TranslationServer::get_locale_name(const String &p_locale) const { @@ -396,8 +411,6 @@ StringName TranslationServer::translate_plural(const StringName &p_message, cons return main_domain->translate_plural(p_message, p_message_plural, p_n, p_context); } -TranslationServer *TranslationServer::singleton = nullptr; - bool TranslationServer::_load_translations(const String &p_from) { if (ProjectSettings::get_singleton()->has_setting(p_from)) { const Vector<String> &translation_names = GLOBAL_GET(p_from); diff --git a/core/string/translation_server.h b/core/string/translation_server.h index 2438349a69..bc59c34a38 100644 --- a/core/string/translation_server.h +++ b/core/string/translation_server.h @@ -50,7 +50,7 @@ class TranslationServer : public Object { bool enabled = true; - static TranslationServer *singleton; + static inline TranslationServer *singleton = nullptr; bool _load_translations(const String &p_from); String _standardize_locale(const String &p_locale, bool p_add_defaults) const; @@ -64,6 +64,24 @@ class TranslationServer : public Object { }; static Vector<LocaleScriptInfo> locale_script_info; + struct Locale { + String language; + String script; + String country; + String variant; + + bool operator==(const Locale &p_locale) const { + return (p_locale.language == language) && + (p_locale.script == script) && + (p_locale.country == country) && + (p_locale.variant == variant); + } + + operator String() const; + + Locale(const TranslationServer &p_server, const String &p_locale, bool p_add_defaults); + }; + static HashMap<String, String> language_map; static HashMap<String, String> script_map; static HashMap<String, String> locale_rename_map; diff --git a/core/templates/a_hash_map.h b/core/templates/a_hash_map.h index 29983ea268..6e3a978d50 100644 --- a/core/templates/a_hash_map.h +++ b/core/templates/a_hash_map.h @@ -622,10 +622,11 @@ public: } // Inserts an element without checking if it already exists. - void insert_new(const TKey &p_key, const TValue &p_value) { + Iterator insert_new(const TKey &p_key, const TValue &p_value) { DEV_ASSERT(!has(p_key)); uint32_t hash = _hash(p_key); - _insert_element(p_key, p_value, hash); + uint32_t pos = _insert_element(p_key, p_value, hash); + return Iterator(elements + pos, elements, elements + num_elements); } /* Array methods. */ diff --git a/core/templates/hashfuncs.h b/core/templates/hashfuncs.h index 7818ed0706..e681835c5a 100644 --- a/core/templates/hashfuncs.h +++ b/core/templates/hashfuncs.h @@ -110,6 +110,16 @@ static _FORCE_INLINE_ uint32_t hash_one_uint64(const uint64_t p_int) { return uint32_t(v); } +static _FORCE_INLINE_ uint64_t hash64_murmur3_64(uint64_t key, uint64_t seed) { + key ^= seed; + key ^= key >> 33; + key *= 0xff51afd7ed558ccd; + key ^= key >> 33; + key *= 0xc4ceb9fe1a85ec53; + key ^= key >> 33; + return key; +} + #define HASH_MURMUR3_SEED 0x7F07C65 // Murmurhash3 32-bit version. // All MurmurHash versions are public domain software, and the author disclaims all copyright to their code. diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp index 5ce90cd8ff..ddeea27118 100644 --- a/core/variant/callable.cpp +++ b/core/variant/callable.cpp @@ -206,19 +206,17 @@ int Callable::get_bound_arguments_count() const { } } -void Callable::get_bound_arguments_ref(Vector<Variant> &r_arguments, int &r_argcount) const { +void Callable::get_bound_arguments_ref(Vector<Variant> &r_arguments) const { if (!is_null() && is_custom()) { - custom->get_bound_arguments(r_arguments, r_argcount); + custom->get_bound_arguments(r_arguments); } else { r_arguments.clear(); - r_argcount = 0; } } Array Callable::get_bound_arguments() const { Vector<Variant> arr; - int ac; - get_bound_arguments_ref(arr, ac); + get_bound_arguments_ref(arr); Array ret; ret.resize(arr.size()); for (int i = 0; i < arr.size(); i++) { @@ -227,6 +225,14 @@ Array Callable::get_bound_arguments() const { return ret; } +int Callable::get_unbound_arguments_count() const { + if (!is_null() && is_custom()) { + return custom->get_unbound_arguments_count(); + } else { + return 0; + } +} + CallableCustom *Callable::get_custom() const { ERR_FAIL_COND_V_MSG(!is_custom(), nullptr, vformat("Can't get custom on non-CallableCustom \"%s\".", operator String())); @@ -464,9 +470,12 @@ int CallableCustom::get_bound_arguments_count() const { return 0; } -void CallableCustom::get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const { - r_arguments = Vector<Variant>(); - r_argcount = 0; +void CallableCustom::get_bound_arguments(Vector<Variant> &r_arguments) const { + r_arguments.clear(); +} + +int CallableCustom::get_unbound_arguments_count() const { + return 0; } CallableCustom::CallableCustom() { diff --git a/core/variant/callable.h b/core/variant/callable.h index e3c940a0e5..e76b888ac2 100644 --- a/core/variant/callable.h +++ b/core/variant/callable.h @@ -111,8 +111,9 @@ public: CallableCustom *get_custom() const; int get_argument_count(bool *r_is_valid = nullptr) const; int get_bound_arguments_count() const; - void get_bound_arguments_ref(Vector<Variant> &r_arguments, int &r_argcount) const; // Internal engine use, the exposed one is below. + void get_bound_arguments_ref(Vector<Variant> &r_arguments) const; // Internal engine use, the exposed one is below. Array get_bound_arguments() const; + int get_unbound_arguments_count() const; uint32_t hash() const; @@ -158,7 +159,8 @@ public: virtual const Callable *get_base_comparator() const; virtual int get_argument_count(bool &r_is_valid) const; virtual int get_bound_arguments_count() const; - virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const; + virtual void get_bound_arguments(Vector<Variant> &r_arguments) const; + virtual int get_unbound_arguments_count() const; CallableCustom(); virtual ~CallableCustom() {} diff --git a/core/variant/callable_bind.cpp b/core/variant/callable_bind.cpp index d82aa3583d..43cac263c1 100644 --- a/core/variant/callable_bind.cpp +++ b/core/variant/callable_bind.cpp @@ -43,7 +43,7 @@ bool CallableCustomBind::_equal_func(const CallableCustom *p_a, const CallableCu const CallableCustomBind *a = static_cast<const CallableCustomBind *>(p_a); const CallableCustomBind *b = static_cast<const CallableCustomBind *>(p_b); - if (!(a->callable != b->callable)) { + if (a->callable != b->callable) { return false; } @@ -100,44 +100,42 @@ int CallableCustomBind::get_argument_count(bool &r_is_valid) const { } int CallableCustomBind::get_bound_arguments_count() const { - return callable.get_bound_arguments_count() + binds.size(); + return callable.get_bound_arguments_count() + MAX(0, binds.size() - callable.get_unbound_arguments_count()); } -void CallableCustomBind::get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const { - Vector<Variant> sub_args; - int sub_count; - callable.get_bound_arguments_ref(sub_args, sub_count); +void CallableCustomBind::get_bound_arguments(Vector<Variant> &r_arguments) const { + Vector<Variant> sub_bound_args; + callable.get_bound_arguments_ref(sub_bound_args); + int sub_bound_count = sub_bound_args.size(); - if (sub_count == 0) { + int sub_unbound_count = callable.get_unbound_arguments_count(); + + if (sub_bound_count == 0 && sub_unbound_count == 0) { r_arguments = binds; - r_argcount = binds.size(); return; } - int new_count = sub_count + binds.size(); - r_argcount = new_count; + int added_count = MAX(0, binds.size() - sub_unbound_count); + int new_count = sub_bound_count + added_count; - if (new_count <= 0) { - // Removed more arguments than it adds. - r_arguments = Vector<Variant>(); + if (added_count <= 0) { + // All added arguments are consumed by `sub_unbound_count`. + r_arguments = sub_bound_args; return; } r_arguments.resize(new_count); - - if (sub_count > 0) { - for (int i = 0; i < sub_count; i++) { - r_arguments.write[i] = sub_args[i]; - } - for (int i = 0; i < binds.size(); i++) { - r_arguments.write[i + sub_count] = binds[i]; - } - r_argcount = new_count; - } else { - for (int i = 0; i < binds.size() + sub_count; i++) { - r_arguments.write[i] = binds[i - sub_count]; - } + Variant *args = r_arguments.ptrw(); + for (int i = 0; i < added_count; i++) { + args[i] = binds[i]; } + for (int i = 0; i < sub_bound_count; i++) { + args[i + added_count] = sub_bound_args[i]; + } +} + +int CallableCustomBind::get_unbound_arguments_count() const { + return MAX(0, callable.get_unbound_arguments_count() - binds.size()); } void CallableCustomBind::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const { @@ -185,7 +183,7 @@ bool CallableCustomUnbind::_equal_func(const CallableCustom *p_a, const Callable const CallableCustomUnbind *a = static_cast<const CallableCustomUnbind *>(p_a); const CallableCustomUnbind *b = static_cast<const CallableCustomUnbind *>(p_b); - if (!(a->callable != b->callable)) { + if (a->callable != b->callable) { return false; } @@ -242,22 +240,15 @@ int CallableCustomUnbind::get_argument_count(bool &r_is_valid) const { } int CallableCustomUnbind::get_bound_arguments_count() const { - return callable.get_bound_arguments_count() - argcount; + return callable.get_bound_arguments_count(); } -void CallableCustomUnbind::get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const { - Vector<Variant> sub_args; - int sub_count; - callable.get_bound_arguments_ref(sub_args, sub_count); - - r_argcount = sub_args.size() - argcount; +void CallableCustomUnbind::get_bound_arguments(Vector<Variant> &r_arguments) const { + callable.get_bound_arguments_ref(r_arguments); +} - if (argcount >= sub_args.size()) { - r_arguments = Vector<Variant>(); - } else { - sub_args.resize(sub_args.size() - argcount); - r_arguments = sub_args; - } +int CallableCustomUnbind::get_unbound_arguments_count() const { + return callable.get_unbound_arguments_count() + argcount; } void CallableCustomUnbind::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const { diff --git a/core/variant/callable_bind.h b/core/variant/callable_bind.h index 43cebb45f0..1346277197 100644 --- a/core/variant/callable_bind.h +++ b/core/variant/callable_bind.h @@ -55,7 +55,8 @@ public: virtual const Callable *get_base_comparator() const override; virtual int get_argument_count(bool &r_is_valid) const override; virtual int get_bound_arguments_count() const override; - virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override; + virtual void get_bound_arguments(Vector<Variant> &r_arguments) const override; + virtual int get_unbound_arguments_count() const override; Callable get_callable() { return callable; } Vector<Variant> get_binds() { return binds; } @@ -84,7 +85,8 @@ public: virtual const Callable *get_base_comparator() const override; virtual int get_argument_count(bool &r_is_valid) const override; virtual int get_bound_arguments_count() const override; - virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override; + virtual void get_bound_arguments(Vector<Variant> &r_arguments) const override; + virtual int get_unbound_arguments_count() const override; Callable get_callable() { return callable; } int get_unbinds() { return argcount; } diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 65bfc29a55..3e74dc4e67 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -951,7 +951,7 @@ bool Variant::is_zero() const { return *reinterpret_cast<const ::RID *>(_data._mem) == ::RID(); } case OBJECT: { - return _get_obj().obj == nullptr; + return get_validated_object() == nullptr; } case CALLABLE: { return reinterpret_cast<const Callable *>(_data._mem)->is_null(); @@ -3664,18 +3664,20 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method, String Variant::get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { Vector<Variant> binds; - int args_bound; - p_callable.get_bound_arguments_ref(binds, args_bound); - if (args_bound <= 0) { - return get_call_error_text(p_callable.get_object(), p_callable.get_method(), p_argptrs, MAX(0, p_argcount + args_bound), ce); + p_callable.get_bound_arguments_ref(binds); + + int args_unbound = p_callable.get_unbound_arguments_count(); + + if (p_argcount - args_unbound < 0) { + return "Callable unbinds " + itos(args_unbound) + " arguments, but called with " + itos(p_argcount); } else { Vector<const Variant *> argptrs; - argptrs.resize(p_argcount + binds.size()); - for (int i = 0; i < p_argcount; i++) { + argptrs.resize(p_argcount - args_unbound + binds.size()); + for (int i = 0; i < p_argcount - args_unbound; i++) { argptrs.write[i] = p_argptrs[i]; } for (int i = 0; i < binds.size(); i++) { - argptrs.write[i + p_argcount] = &binds[i]; + argptrs.write[i + p_argcount - args_unbound] = &binds[i]; } return get_call_error_text(p_callable.get_object(), p_callable.get_method(), (const Variant **)argptrs.ptr(), argptrs.size(), ce); } diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 29e11462c9..381b848b2b 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -2116,6 +2116,7 @@ static void _register_variant_builtin_methods_misc() { bind_function(Callable, get_argument_count, _VariantCall::func_Callable_get_argument_count, sarray(), varray()); bind_method(Callable, get_bound_arguments_count, sarray(), varray()); bind_method(Callable, get_bound_arguments, sarray(), varray()); + bind_method(Callable, get_unbound_arguments_count, sarray(), varray()); bind_method(Callable, hash, sarray(), varray()); bind_method(Callable, bindv, sarray("arguments"), varray()); bind_method(Callable, unbind, sarray("argcount"), varray()); diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index 1652f81d99..560067fc08 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -141,6 +141,10 @@ void register_named_setters_getters() { REGISTER_MEMBER(Color, h); REGISTER_MEMBER(Color, s); REGISTER_MEMBER(Color, v); + + REGISTER_MEMBER(Color, ok_hsl_h); + REGISTER_MEMBER(Color, ok_hsl_s); + REGISTER_MEMBER(Color, ok_hsl_l); } void unregister_named_setters_getters() { diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 66f15f7494..ce64bcc17c 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -991,8 +991,8 @@ [codeblock] var a = rand_from_seed(4) - print(a[0]) # Prints 2879024997 - print(a[1]) # Prints 4 + print(a[0]) # Prints 2879024997 + print(a[1]) # Prints 4 [/codeblock] </description> </method> @@ -2992,7 +2992,7 @@ <constant name="PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE" value="32768" enum="PropertyUsageFlags" is_bitfield="true" deprecated="This flag is not used by the engine."> </constant> <constant name="PROPERTY_USAGE_CLASS_IS_ENUM" value="65536" enum="PropertyUsageFlags" is_bitfield="true"> - The property is an enum, i.e. it only takes named integer constants from its associated enumeration. + The property is a variable of enum type, i.e. it only takes named integer constants from its associated enumeration. </constant> <constant name="PROPERTY_USAGE_NIL_IS_VARIANT" value="131072" enum="PropertyUsageFlags" is_bitfield="true"> If property has [code]nil[/code] as default value, its type will be [Variant]. diff --git a/doc/classes/AStar2D.xml b/doc/classes/AStar2D.xml index a41da4c318..044e1206e9 100644 --- a/doc/classes/AStar2D.xml +++ b/doc/classes/AStar2D.xml @@ -278,7 +278,7 @@ <return type="void" /> <param index="0" name="num_nodes" type="int" /> <description> - Reserves space internally for [param num_nodes] points, useful if you're adding a known large number of points at once, such as points on a grid. New capacity must be greater or equals to old capacity. + Reserves space internally for [param num_nodes] points. Useful if you're adding a known large number of points at once, such as points on a grid. The new capacity must be greater or equal to the old capacity. </description> </method> <method name="set_point_disabled"> diff --git a/doc/classes/AnimatedSprite2D.xml b/doc/classes/AnimatedSprite2D.xml index 88e543591a..cc1e9117f9 100644 --- a/doc/classes/AnimatedSprite2D.xml +++ b/doc/classes/AnimatedSprite2D.xml @@ -55,7 +55,7 @@ <param index="1" name="progress" type="float" /> <description> Sets [member frame] the [member frame_progress] to the given values. Unlike setting [member frame], this method does not reset the [member frame_progress] to [code]0.0[/code] implicitly. - [b]Example:[/b] Change the animation while keeping the same [member frame] and [member frame_progress]. + [b]Example:[/b] Change the animation while keeping the same [member frame] and [member frame_progress]: [codeblocks] [gdscript] var current_frame = animated_sprite.get_frame() diff --git a/doc/classes/AnimatedSprite3D.xml b/doc/classes/AnimatedSprite3D.xml index a466fc32ac..1b1f58e5f4 100644 --- a/doc/classes/AnimatedSprite3D.xml +++ b/doc/classes/AnimatedSprite3D.xml @@ -54,7 +54,7 @@ <param index="1" name="progress" type="float" /> <description> Sets [member frame] the [member frame_progress] to the given values. Unlike setting [member frame], this method does not reset the [member frame_progress] to [code]0.0[/code] implicitly. - [b]Example:[/b] Change the animation while keeping the same [member frame] and [member frame_progress]. + [b]Example:[/b] Change the animation while keeping the same [member frame] and [member frame_progress]: [codeblocks] [gdscript] var current_frame = animated_sprite.get_frame() diff --git a/doc/classes/AnimationNodeAnimation.xml b/doc/classes/AnimationNodeAnimation.xml index 70c3e5a26e..f4490bc167 100644 --- a/doc/classes/AnimationNodeAnimation.xml +++ b/doc/classes/AnimationNodeAnimation.xml @@ -12,6 +12,10 @@ <link title="Third Person Shooter (TPS) Demo">https://godotengine.org/asset-library/asset/2710</link> </tutorials> <members> + <member name="advance_on_start" type="bool" setter="set_advance_on_start" getter="is_advance_on_start" default="false"> + If [code]true[/code], on receiving a request to play an animation from the start, the first frame is not drawn, but only processed, and playback starts from the next frame. + See also the notes of [method AnimationPlayer.play]. + </member> <member name="animation" type="StringName" setter="set_animation" getter="get_animation" default="&"""> Animation to use as an output. It is one of the animations provided by [member AnimationTree.anim_player]. </member> diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml index 4ad5db2b67..61a103f20d 100644 --- a/doc/classes/Area2D.xml +++ b/doc/classes/Area2D.xml @@ -132,7 +132,7 @@ <description> Emitted when a [Shape2D] of the received [param area] enters a shape of this area. Requires [member monitoring] to be set to [code]true[/code]. [param local_shape_index] and [param area_shape_index] contain indices of the interacting shapes from this area and the other area, respectively. [param area_rid] contains the [RID] of the other area. These values can be used with the [PhysicsServer2D]. - [b]Example of getting the[/b] [CollisionShape2D] [b]node from the shape index:[/b] + [b]Example:[/b] Get the [CollisionShape2D] node from the shape index: [codeblocks] [gdscript] var other_shape_owner = area.shape_find_owner(area_shape_index) @@ -174,7 +174,7 @@ <description> Emitted when a [Shape2D] of the received [param body] enters a shape of this area. [param body] can be a [PhysicsBody2D] or a [TileMap]. [TileMap]s are detected if their [TileSet] has collision shapes configured. Requires [member monitoring] to be set to [code]true[/code]. [param local_shape_index] and [param body_shape_index] contain indices of the interacting shapes from this area and the interacting body, respectively. [param body_rid] contains the [RID] of the body. These values can be used with the [PhysicsServer2D]. - [b]Example of getting the[/b] [CollisionShape2D] [b]node from the shape index:[/b] + [b]Example:[/b] Get the [CollisionShape2D] node from the shape index: [codeblocks] [gdscript] var body_shape_owner = body.shape_find_owner(body_shape_index) diff --git a/doc/classes/Area3D.xml b/doc/classes/Area3D.xml index 8eedd3cdf2..aac98593ff 100644 --- a/doc/classes/Area3D.xml +++ b/doc/classes/Area3D.xml @@ -156,7 +156,7 @@ <description> Emitted when a [Shape3D] of the received [param area] enters a shape of this area. Requires [member monitoring] to be set to [code]true[/code]. [param local_shape_index] and [param area_shape_index] contain indices of the interacting shapes from this area and the other area, respectively. [param area_rid] contains the [RID] of the other area. These values can be used with the [PhysicsServer3D]. - [b]Example of getting the[/b] [CollisionShape3D] [b]node from the shape index:[/b] + [b]Example:[/b] Get the [CollisionShape3D] node from the shape index: [codeblocks] [gdscript] var other_shape_owner = area.shape_find_owner(area_shape_index) @@ -198,7 +198,7 @@ <description> Emitted when a [Shape3D] of the received [param body] enters a shape of this area. [param body] can be a [PhysicsBody3D] or a [GridMap]. [GridMap]s are detected if their [MeshLibrary] has collision shapes configured. Requires [member monitoring] to be set to [code]true[/code]. [param local_shape_index] and [param body_shape_index] contain indices of the interacting shapes from this area and the interacting body, respectively. [param body_rid] contains the [RID] of the body. These values can be used with the [PhysicsServer3D]. - [b]Example of getting the[/b] [CollisionShape3D] [b]node from the shape index:[/b] + [b]Example:[/b] Get the [CollisionShape3D] node from the shape index: [codeblocks] [gdscript] var body_shape_owner = body.shape_find_owner(body_shape_index) diff --git a/doc/classes/AudioEffectSpectrumAnalyzer.xml b/doc/classes/AudioEffectSpectrumAnalyzer.xml index b90f87ef5b..5cbf3fb1cb 100644 --- a/doc/classes/AudioEffectSpectrumAnalyzer.xml +++ b/doc/classes/AudioEffectSpectrumAnalyzer.xml @@ -5,7 +5,7 @@ </brief_description> <description> This audio effect does not affect sound output, but can be used for real-time audio visualizations. - This resource configures an [AudioEffectSpectrumAnalyzerInstance], which performs the actual analysis at runtime. An instance can be acquired with [method AudioServer.get_bus_effect_instance]. + This resource configures an [AudioEffectSpectrumAnalyzerInstance], which performs the actual analysis at runtime. An instance can be obtained with [method AudioServer.get_bus_effect_instance]. See also [AudioStreamGenerator] for procedurally generating sounds. </description> <tutorials> diff --git a/doc/classes/AudioEffectSpectrumAnalyzerInstance.xml b/doc/classes/AudioEffectSpectrumAnalyzerInstance.xml index 184f80db2e..833ccafa6f 100644 --- a/doc/classes/AudioEffectSpectrumAnalyzerInstance.xml +++ b/doc/classes/AudioEffectSpectrumAnalyzerInstance.xml @@ -5,7 +5,7 @@ </brief_description> <description> The runtime part of an [AudioEffectSpectrumAnalyzer], which can be used to query the magnitude of a frequency range on its host bus. - An instance of this class can be acquired with [method AudioServer.get_bus_effect_instance]. + An instance of this class can be obtained with [method AudioServer.get_bus_effect_instance]. </description> <tutorials> <link title="Audio Spectrum Visualizer Demo">https://godotengine.org/asset-library/asset/2762</link> diff --git a/doc/classes/Basis.xml b/doc/classes/Basis.xml index 322d2ab9d4..59c1195b00 100644 --- a/doc/classes/Basis.xml +++ b/doc/classes/Basis.xml @@ -25,6 +25,7 @@ <return type="Basis" /> <description> Constructs a [Basis] identical to the [constant IDENTITY]. + [b]Note:[/b] In C#, this constructs a [Basis] with all of its components set to [constant Vector3.ZERO]. </description> </constructor> <constructor name="Basis"> @@ -303,7 +304,7 @@ <param index="1" name="weight" type="float" /> <description> Performs a spherical-linear interpolation with the [param to] basis, given a [param weight]. Both this basis and [param to] should represent a rotation. - [b]Example:[/b] Smoothly rotate a [Node3D] to the target basis over time, with a [Tween]. + [b]Example:[/b] Smoothly rotate a [Node3D] to the target basis over time, with a [Tween]: [codeblock] var start_basis = Basis.IDENTITY var target_basis = Basis.IDENTITY.rotated(Vector3.UP, TAU / 2) diff --git a/doc/classes/Button.xml b/doc/classes/Button.xml index c774667a7d..5b3f86c9f5 100644 --- a/doc/classes/Button.xml +++ b/doc/classes/Button.xml @@ -5,13 +5,13 @@ </brief_description> <description> [Button] is the standard themed button. It can contain text and an icon, and it will display them according to the current [Theme]. - [b]Example of creating a button and assigning an action when pressed by code:[/b] + [b]Example:[/b] Create a button and connect a method that will be called when the button is pressed: [codeblocks] [gdscript] func _ready(): var button = Button.new() button.text = "Click me" - button.pressed.connect(self._button_pressed) + button.pressed.connect(_button_pressed) add_child(button) func _button_pressed(): @@ -33,7 +33,7 @@ [/csharp] [/codeblocks] See also [BaseButton] which contains common properties and methods associated with this node. - [b]Note:[/b] Buttons do not interpret touch input and therefore don't support multitouch, since mouse emulation can only press one button at a given time. Use [TouchScreenButton] for buttons that trigger gameplay movement or actions. + [b]Note:[/b] Buttons do not detect touch input and therefore don't support multitouch, since mouse emulation can only press one button at a given time. Use [TouchScreenButton] for buttons that trigger gameplay movement or actions. </description> <tutorials> <link title="2D Dodge The Creeps Demo">https://godotengine.org/asset-library/asset/2712</link> diff --git a/doc/classes/CPUParticles2D.xml b/doc/classes/CPUParticles2D.xml index 99411c73aa..e8fa13fd0d 100644 --- a/doc/classes/CPUParticles2D.xml +++ b/doc/classes/CPUParticles2D.xml @@ -43,7 +43,7 @@ <return type="bool" /> <param index="0" name="particle_flag" type="int" enum="CPUParticles2D.ParticleFlags" /> <description> - Returns the enabled state of the given flag (see [enum ParticleFlags] for options). + Returns the enabled state of the given particle flag (see [enum ParticleFlags] for options). </description> </method> <method name="restart"> diff --git a/doc/classes/Callable.xml b/doc/classes/Callable.xml index 0c8f3c66f5..cf3c3e06fd 100644 --- a/doc/classes/Callable.xml +++ b/doc/classes/Callable.xml @@ -155,13 +155,21 @@ <method name="get_bound_arguments" qualifiers="const"> <return type="Array" /> <description> - Return the bound arguments (as long as [method get_bound_arguments_count] is greater than zero), or empty (if [method get_bound_arguments_count] is less than or equal to zero). + Returns the array of arguments bound via successive [method bind] or [method unbind] calls. These arguments will be added [i]after[/i] the arguments passed to the call, from which [method get_unbound_arguments_count] arguments on the right have been previously excluded. + [codeblock] + func get_effective_arguments(callable, call_args): + assert(call_args.size() - callable.get_unbound_arguments_count() >= 0) + var result = call_args.slice(0, call_args.size() - callable.get_unbound_arguments_count()) + result.append_array(callable.get_bound_arguments()) + return result + [/codeblock] </description> </method> <method name="get_bound_arguments_count" qualifiers="const"> <return type="int" /> <description> - Returns the total amount of arguments bound (or unbound) via successive [method bind] or [method unbind] calls. If the amount of arguments unbound is greater than the ones bound, this function returns a value less than zero. + Returns the total amount of arguments bound via successive [method bind] or [method unbind] calls. This is the same as the size of the array returned by [method get_bound_arguments]. See [method get_bound_arguments] for details. + [b]Note:[/b] The [method get_bound_arguments_count] and [method get_unbound_arguments_count] methods can both return positive values. </description> </method> <method name="get_method" qualifiers="const"> @@ -182,6 +190,13 @@ Returns the ID of this [Callable]'s object (see [method Object.get_instance_id]). </description> </method> + <method name="get_unbound_arguments_count" qualifiers="const"> + <return type="int" /> + <description> + Returns the total amount of arguments unbound via successive [method bind] or [method unbind] calls. See [method get_bound_arguments] for details. + [b]Note:[/b] The [method get_bound_arguments_count] and [method get_unbound_arguments_count] methods can both return positive values. + </description> + </method> <method name="hash" qualifiers="const"> <return type="int" /> <description> diff --git a/doc/classes/CallbackTweener.xml b/doc/classes/CallbackTweener.xml index afb9e70601..3a617d2a43 100644 --- a/doc/classes/CallbackTweener.xml +++ b/doc/classes/CallbackTweener.xml @@ -16,7 +16,7 @@ <param index="0" name="delay" type="float" /> <description> Makes the callback call delayed by given time in seconds. - [b]Example:[/b] Call [method Node.queue_free] after 2 seconds. + [b]Example:[/b] Call [method Node.queue_free] after 2 seconds: [codeblock] var tween = get_tree().create_tween() tween.tween_callback(queue_free).set_delay(2) diff --git a/doc/classes/CameraAttributes.xml b/doc/classes/CameraAttributes.xml index 1b1365eed4..cb5a7778de 100644 --- a/doc/classes/CameraAttributes.xml +++ b/doc/classes/CameraAttributes.xml @@ -25,7 +25,9 @@ Multiplier for the exposure amount. A higher value results in a brighter image. </member> <member name="exposure_sensitivity" type="float" setter="set_exposure_sensitivity" getter="get_exposure_sensitivity" default="100.0"> - Sensitivity of camera sensors, measured in ISO. A higher sensitivity results in a brighter image. Only available when [member ProjectSettings.rendering/lights_and_shadows/use_physical_light_units] is enabled. When [member auto_exposure_enabled] this can be used as a method of exposure compensation, doubling the value will increase the exposure value (measured in EV100) by 1 stop. + Sensitivity of camera sensors, measured in ISO. A higher sensitivity results in a brighter image. + If [member auto_exposure_enabled] is [code]true[/code], this can be used as a method of exposure compensation, doubling the value will increase the exposure value (measured in EV100) by 1 stop. + [b]Note:[/b] Only available when [member ProjectSettings.rendering/lights_and_shadows/use_physical_light_units] is enabled. </member> </members> </class> diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index 78e9c392db..5710e08423 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -333,7 +333,7 @@ <param index="9" name="orientation" type="int" enum="TextServer.Orientation" default="0" /> <description> Draws [param text] using the specified [param font] at the [param pos] (bottom-left corner using the baseline of the font). The text will have its color multiplied by [param modulate]. If [param width] is greater than or equal to 0, the text will be clipped if it exceeds the specified width. - [b]Example using the default project font:[/b] + [b]Example:[/b] Draw "Hello world", using the project's default font: [codeblocks] [gdscript] # If using this method in a script that redraws constantly, move the @@ -594,6 +594,7 @@ <members> <member name="clip_children" type="int" setter="set_clip_children_mode" getter="get_clip_children_mode" enum="CanvasItem.ClipChildrenMode" default="0"> Allows the current node to clip child nodes, essentially acting as a mask. + [b]Note:[/b] Clipping nodes cannot be nested or placed within [CanvasGroup]s. If an ancestor of this node clips its children or is a [CanvasGroup], then this node's clip mode should be set to [constant CLIP_CHILDREN_DISABLED] to avoid unexpected behavior. </member> <member name="light_mask" type="int" setter="set_light_mask" getter="get_light_mask" default="1"> The rendering layers in which this [CanvasItem] responds to [Light2D] nodes. @@ -632,7 +633,7 @@ </member> <member name="y_sort_enabled" type="bool" setter="set_y_sort_enabled" getter="is_y_sort_enabled" default="false"> If [code]true[/code], this and child [CanvasItem] nodes with a higher Y position are rendered in front of nodes with a lower Y position. If [code]false[/code], this and child [CanvasItem] nodes are rendered normally in scene tree order. - With Y-sorting enabled on a parent node ('A') but disabled on a child node ('B'), the child node ('B') is sorted but its children ('C1', 'C2', etc) render together on the same Y position as the child node ('B'). This allows you to organize the render order of a scene without changing the scene tree. + With Y-sorting enabled on a parent node ('A') but disabled on a child node ('B'), the child node ('B') is sorted but its children ('C1', 'C2', etc.) render together on the same Y position as the child node ('B'). This allows you to organize the render order of a scene without changing the scene tree. Nodes sort relative to each other only if they are on the same [member z_index]. </member> <member name="z_as_relative" type="bool" setter="set_z_as_relative" getter="is_z_relative" default="true"> diff --git a/doc/classes/CharFXTransform.xml b/doc/classes/CharFXTransform.xml index 403033f85d..28f5d38ee4 100644 --- a/doc/classes/CharFXTransform.xml +++ b/doc/classes/CharFXTransform.xml @@ -8,7 +8,6 @@ </description> <tutorials> <link title="BBCode in RichTextLabel">$DOCS_URL/tutorials/ui/bbcode_in_richtextlabel.html</link> - <link title="RichTextEffect test project (third-party)">https://github.com/Eoin-ONeill-Yokai/Godot-Rich-Text-Effect-Test-Project</link> </tutorials> <members> <member name="color" type="Color" setter="set_color" getter="get_color" default="Color(0, 0, 0, 1)" keywords="colour"> diff --git a/doc/classes/CharacterBody2D.xml b/doc/classes/CharacterBody2D.xml index ede4d63cfc..30438be18b 100644 --- a/doc/classes/CharacterBody2D.xml +++ b/doc/classes/CharacterBody2D.xml @@ -69,7 +69,7 @@ <param index="0" name="slide_idx" type="int" /> <description> Returns a [KinematicCollision2D], which contains information about a collision that occurred during the last call to [method move_and_slide]. Since the body can collide several times in a single call to [method move_and_slide], you must specify the index of the collision in the range 0 to ([method get_slide_collision_count] - 1). - [b]Example usage:[/b] + [b]Example:[/b] Iterate through the collisions with a [code]for[/code] loop: [codeblocks] [gdscript] for i in get_slide_collision_count(): diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml index 9fe42fff90..546d90fa3c 100644 --- a/doc/classes/Color.xml +++ b/doc/classes/Color.xml @@ -19,7 +19,7 @@ <return type="Color" /> <description> Constructs a default [Color] from opaque black. This is the same as [constant BLACK]. - [b]Note:[/b] in C#, constructs an empty color with all of its components set to [code]0.0[/code] (transparent black). + [b]Note:[/b] In C#, this constructs a [Color] with all of its components set to [code]0.0[/code] (transparent black). </description> </constructor> <constructor name="Color"> @@ -495,6 +495,15 @@ <member name="h" type="float" setter="" getter="" default="0.0"> The HSV hue of this color, on the range 0 to 1. </member> + <member name="ok_hsl_h" type="float" setter="" getter="" default="0.0"> + The OKHSL hue of this color, on the range 0 to 1. + </member> + <member name="ok_hsl_l" type="float" setter="" getter="" default="0.0"> + The OKHSL lightness of this color, on the range 0 to 1. + </member> + <member name="ok_hsl_s" type="float" setter="" getter="" default="0.0"> + The OKHSL saturation of this color, on the range 0 to 1. + </member> <member name="r" type="float" setter="" getter="" default="0.0"> The color's red component, typically on the range of 0 to 1. </member> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index 0131f8f4af..342e20759e 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -120,8 +120,8 @@ <return type="void" /> <param index="0" name="event" type="InputEvent" /> <description> - Virtual method to be implemented by the user. Use this method to process and accept inputs on UI elements. See [method accept_event]. - [b]Example usage for clicking a control:[/b] + Virtual method to be implemented by the user. Override this method to handle and accept inputs on UI elements. See also [method accept_event]. + [b]Example:[/b] Click on the control to print a message: [codeblocks] [gdscript] func _gui_input(event): @@ -142,13 +142,13 @@ } [/csharp] [/codeblocks] - The event won't trigger if: - * clicking outside the control (see [method _has_point]); - * control has [member mouse_filter] set to [constant MOUSE_FILTER_IGNORE]; - * control is obstructed by another [Control] on top of it, which doesn't have [member mouse_filter] set to [constant MOUSE_FILTER_IGNORE]; - * control's parent has [member mouse_filter] set to [constant MOUSE_FILTER_STOP] or has accepted the event; - * it happens outside the parent's rectangle and the parent has either [member clip_contents] enabled. - [b]Note:[/b] Event position is relative to the control origin. + If the [param event] inherits [InputEventMouse], this method will [b]not[/b] be called when: + - the control's [member mouse_filter] is set to [constant MOUSE_FILTER_IGNORE]; + - the control is obstructed by another control on top, that doesn't have [member mouse_filter] set to [constant MOUSE_FILTER_IGNORE]; + - the control's parent has [member mouse_filter] set to [constant MOUSE_FILTER_STOP] or has accepted the event; + - the control's parent has [member clip_contents] enabled and the [param event]'s position is outside the parent's rectangle; + - the [param event]'s position is outside the control (see [method _has_point]). + [b]Note:[/b] The [param event]'s position is relative to this control's origin. </description> </method> <method name="_has_point" qualifiers="virtual const"> @@ -168,8 +168,8 @@ The returned node must be of type [Control] or Control-derived. It can have child nodes of any type. It is freed when the tooltip disappears, so make sure you always provide a new instance (if you want to use a pre-existing node from your scene tree, you can duplicate it and pass the duplicated instance). When [code]null[/code] or a non-Control node is returned, the default tooltip will be used instead. The returned node will be added as child to a [PopupPanel], so you should only provide the contents of that panel. That [PopupPanel] can be themed using [method Theme.set_stylebox] for the type [code]"TooltipPanel"[/code] (see [member tooltip_text] for an example). [b]Note:[/b] The tooltip is shrunk to minimal size. If you want to ensure it's fully visible, you might want to set its [member custom_minimum_size] to some non-zero value. - [b]Note:[/b] The node (and any relevant children) should be [member CanvasItem.visible] when returned, otherwise, the viewport that instantiates it will not be able to calculate its minimum size reliably. - [b]Example of usage with a custom-constructed node:[/b] + [b]Note:[/b] The node (and any relevant children) should have their [member CanvasItem.visible] set to [code]true[/code] when returned, otherwise, the viewport that instantiates it will not be able to calculate its minimum size reliably. + [b]Example:[/b] Use a constructed node as a tooltip: [codeblocks] [gdscript] func _make_custom_tooltip(for_text): @@ -186,7 +186,7 @@ } [/csharp] [/codeblocks] - [b]Example of usage with a custom scene instance:[/b] + [b]Example:[/b] Usa a scene instance as a tooltip: [codeblocks] [gdscript] func _make_custom_tooltip(for_text): @@ -228,7 +228,7 @@ <description> Creates a local override for a theme [Color] with the specified [param name]. Local overrides always take precedence when fetching theme items for the control. An override can be removed with [method remove_theme_color_override]. See also [method get_theme_color]. - [b]Example of overriding a label's color and resetting it later:[/b] + [b]Example:[/b] Override a [Label]'s color and reset it later: [codeblocks] [gdscript] # Given the child Label node "MyLabel", override its font color with a custom value. @@ -292,10 +292,10 @@ <description> Creates a local override for a theme [StyleBox] with the specified [param name]. Local overrides always take precedence when fetching theme items for the control. An override can be removed with [method remove_theme_stylebox_override]. See also [method get_theme_stylebox]. - [b]Example of modifying a property in a StyleBox by duplicating it:[/b] + [b]Example:[/b] Modify a property in a [StyleBox] by duplicating it: [codeblocks] [gdscript] - # The snippet below assumes the child node MyButton has a StyleBoxFlat assigned. + # The snippet below assumes the child node "MyButton" has a StyleBoxFlat assigned. # Resources are shared across instances, so we need to duplicate it # to avoid modifying the appearance of all other buttons. var new_stylebox_normal = $MyButton.get_theme_stylebox("normal").duplicate() @@ -306,7 +306,7 @@ $MyButton.remove_theme_stylebox_override("normal") [/gdscript] [csharp] - // The snippet below assumes the child node MyButton has a StyleBoxFlat assigned. + // The snippet below assumes the child node "MyButton" has a StyleBoxFlat assigned. // Resources are shared across instances, so we need to duplicate it // to avoid modifying the appearance of all other buttons. StyleBoxFlat newStyleboxNormal = GetNode<Button>("MyButton").GetThemeStylebox("normal").Duplicate() as StyleBoxFlat; @@ -446,7 +446,7 @@ <description> Returns the position of this [Control] in global screen coordinates (i.e. taking window position into account). Mostly useful for editor plugins. Equals to [member global_position] if the window is embedded (see [member Viewport.gui_embed_subwindows]). - [b]Example usage for showing a popup:[/b] + [b]Example:[/b] Show a popup at the mouse position: [codeblock] popup_menu.position = get_screen_position() + get_local_mouse_position() popup_menu.reset_size() @@ -559,7 +559,7 @@ <method name="grab_click_focus"> <return type="void" /> <description> - Creates an [InputEventMouseButton] that attempts to click the control. If the event is received, the control acquires focus. + Creates an [InputEventMouseButton] that attempts to click the control. If the event is received, the control gains focus. [codeblocks] [gdscript] func _process(delta): @@ -809,9 +809,11 @@ <param index="1" name="can_drop_func" type="Callable" /> <param index="2" name="drop_func" type="Callable" /> <description> - Forwards the handling of this control's [method _get_drag_data], [method _can_drop_data] and [method _drop_data] virtual functions to delegate callables. - For each argument, if not empty, the delegate callable is used, otherwise the local (virtual) function is used. - The function format for each callable should be exactly the same as the virtual functions described above. + Sets the given callables to be used instead of the control's own drag-and-drop virtual methods. If a callable is empty, its respective virtual method is used as normal. + The arguments for each callable should be exactly the same as their respective virtual methods, which would be: + - [param drag_func] corresponds to [method _get_drag_data] and requires a [Vector2]; + - [param can_drop_func] corresponds to [method _can_drop_data] and requires both a [Vector2] and a [Variant]; + - [param drop_func] corresponds to [method _drop_data] and requires both a [Vector2] and a [Variant]. </description> </method> <method name="set_drag_preview"> diff --git a/doc/classes/Cubemap.xml b/doc/classes/Cubemap.xml index b7da3c4ec6..8a850920f7 100644 --- a/doc/classes/Cubemap.xml +++ b/doc/classes/Cubemap.xml @@ -6,8 +6,27 @@ <description> A cubemap is made of 6 textures organized in layers. They are typically used for faking reflections in 3D rendering (see [ReflectionProbe]). It can be used to make an object look as if it's reflecting its surroundings. This usually delivers much better performance than other reflection methods. This resource is typically used as a uniform in custom shaders. Few core Godot methods make use of [Cubemap] resources. - To create such a texture file yourself, reimport your image files using the Godot Editor import presets. - [b]Note:[/b] Godot doesn't support using cubemaps in a [PanoramaSkyMaterial]. You can use [url=https://danilw.github.io/GLSL-howto/cubemap_to_panorama_js/cubemap_to_panorama.html]this tool[/url] to convert a cubemap to an equirectangular sky map. + To create such a texture file yourself, reimport your image files using the Godot Editor import presets. The expected image order is X+, X-, Y+, Y-, Z+, Z- (in Godot's coordinate system, so Y+ is "up" and Z- is "forward"). You can use one of the following templates as a base: + - [url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/cubemap_template_2x3.webp]2×3 cubemap template (default layout option)[/url] + - [url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/cubemap_template_3x2.webp]3×2 cubemap template[/url] + - [url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/cubemap_template_1x6.webp]1×6 cubemap template[/url] + - [url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/cubemap_template_6x1.webp]6×1 cubemap template[/url] + [b]Note:[/b] Godot doesn't support using cubemaps in a [PanoramaSkyMaterial]. To use a cubemap as a skybox, convert the default [PanoramaSkyMaterial] to a [ShaderMaterial] using the [b]Convert to ShaderMaterial[/b] resource dropdown option, then replace its code with the following: + [codeblock lang=text] + shader_type sky; + + uniform samplerCube source_panorama : filter_linear, source_color, hint_default_black; + uniform float exposure : hint_range(0, 128) = 1.0; + + void sky() { + // If importing a cubemap from another engine, you may need to flip one of the `EYEDIR` components below + // by replacing it with `-EYEDIR`. + vec3 eyedir = vec3(EYEDIR.x, EYEDIR.y, EYEDIR.z); + COLOR = texture(source_panorama, eyedir).rgb * exposure; + } + [/codeblock] + After replacing the shader code and saving, specify the imported Cubemap resource in the Shader Parameters section of the ShaderMaterial in the inspector. + Alternatively, you can use [url=https://danilw.github.io/GLSL-howto/cubemap_to_panorama_js/cubemap_to_panorama.html]this tool[/url] to convert a cubemap to an equirectangular sky map and use [PanoramaSkyMaterial] as usual. </description> <tutorials> </tutorials> diff --git a/doc/classes/DirAccess.xml b/doc/classes/DirAccess.xml index 9c71addf0c..dcd2d527e2 100644 --- a/doc/classes/DirAccess.xml +++ b/doc/classes/DirAccess.xml @@ -60,6 +60,7 @@ } [/csharp] [/codeblocks] + Keep in mind that file names may change or be remapped after export. If you want to see the actual resource file list as it appears in the editor, use [method ResourceLoader.list_directory] instead. </description> <tutorials> <link title="File system">$DOCS_URL/tutorials/scripting/filesystem.html</link> diff --git a/doc/classes/EditorExportPlugin.xml b/doc/classes/EditorExportPlugin.xml index dc1cd89642..23e3f4139c 100644 --- a/doc/classes/EditorExportPlugin.xml +++ b/doc/classes/EditorExportPlugin.xml @@ -35,9 +35,16 @@ <param index="0" name="resource" type="Resource" /> <param index="1" name="path" type="String" /> <description> - Customize a resource. If changes are made to it, return the same or a new resource. Otherwise, return [code]null[/code]. - The [i]path[/i] argument is only used when customizing an actual file, otherwise this means that this resource is part of another one and it will be empty. + Customize a resource. If changes are made to it, return the same or a new resource. Otherwise, return [code]null[/code]. When a new resource is returned, [param resource] will be replaced by a copy of the new resource. + The [param path] argument is only used when customizing an actual file, otherwise this means that this resource is part of another one and it will be empty. Implementing this method is required if [method _begin_customize_resources] returns [code]true[/code]. + [b]Note:[/b] When customizing any of the following types and returning another resource, the other resource should not be skipped using [method skip] in [method _export_file]: + - [AtlasTexture] + - [CompressedCubemap] + - [CompressedCubemapArray] + - [CompressedTexture2D] + - [CompressedTexture2DArray] + - [CompressedTexture3D] </description> </method> <method name="_customize_scene" qualifiers="virtual"> diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml index e5f3010366..186f249281 100644 --- a/doc/classes/EditorImportPlugin.xml +++ b/doc/classes/EditorImportPlugin.xml @@ -154,7 +154,7 @@ <param index="1" name="option_name" type="StringName" /> <param index="2" name="options" type="Dictionary" /> <description> - This method can be overridden to hide specific import options if conditions are met. This is mainly useful for hiding options that depend on others if one of them is disabled. For example: + This method can be overridden to hide specific import options if conditions are met. This is mainly useful for hiding options that depend on others if one of them is disabled. [codeblocks] [gdscript] func _get_option_visibility(option, options): diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml index 43059db8b2..624e828520 100644 --- a/doc/classes/EditorInterface.xml +++ b/doc/classes/EditorInterface.xml @@ -117,6 +117,12 @@ [b]Note:[/b] When creating custom editor UI, prefer accessing theme items directly from your GUI nodes using the [code]get_theme_*[/code] methods. </description> </method> + <method name="get_editor_toaster" qualifiers="const"> + <return type="EditorToaster" /> + <description> + Returns the editor's [EditorToaster]. + </description> + </method> <method name="get_editor_undo_redo" qualifiers="const"> <return type="EditorUndoRedoManager" /> <description> @@ -301,6 +307,15 @@ See also [method Window.set_unparent_when_invisible]. </description> </method> + <method name="popup_method_selector"> + <return type="void" /> + <param index="0" name="object" type="Object" /> + <param index="1" name="callback" type="Callable" /> + <param index="2" name="current_value" type="String" default="""" /> + <description> + Pops up an editor dialog for selecting a method from [param object]. The [param callback] must take a single argument of type [String] which will contain the name of the selected method or be empty if the dialog is canceled. If [param current_value] is provided, the method will be selected automatically in the method list, if it exists. + </description> + </method> <method name="popup_node_selector"> <return type="void" /> <param index="0" name="callback" type="Callable" /> diff --git a/doc/classes/EditorNode3DGizmoPlugin.xml b/doc/classes/EditorNode3DGizmoPlugin.xml index 8fd7c167d9..6a91e3559d 100644 --- a/doc/classes/EditorNode3DGizmoPlugin.xml +++ b/doc/classes/EditorNode3DGizmoPlugin.xml @@ -54,7 +54,7 @@ <return type="EditorNode3DGizmo" /> <param index="0" name="for_node_3d" type="Node3D" /> <description> - Override this method to return a custom [EditorNode3DGizmo] for the spatial nodes of your choice, return [code]null[/code] for the rest of nodes. See also [method _has_gizmo]. + Override this method to return a custom [EditorNode3DGizmo] for the 3D nodes of your choice, return [code]null[/code] for the rest of nodes. See also [method _has_gizmo]. </description> </method> <method name="_get_gizmo_name" qualifiers="virtual const"> diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml index 8189f253fb..2cc9e08dd3 100644 --- a/doc/classes/EditorPlugin.xml +++ b/doc/classes/EditorPlugin.xml @@ -416,7 +416,7 @@ <param index="1" name="title" type="String" /> <param index="2" name="shortcut" type="Shortcut" default="null" /> <description> - Adds a control to the bottom panel (together with Output, Debug, Animation, etc). Returns a reference to the button added. It's up to you to hide/show the button when needed. When your plugin is deactivated, make sure to remove your custom control with [method remove_control_from_bottom_panel] and free it with [method Node.queue_free]. + Adds a control to the bottom panel (together with Output, Debug, Animation, etc.). Returns a reference to the button added. It's up to you to hide/show the button when needed. When your plugin is deactivated, make sure to remove your custom control with [method remove_control_from_bottom_panel] and free it with [method Node.queue_free]. Optionally, you can specify a shortcut parameter. When pressed, this shortcut will toggle the bottom panel's visibility. See the default editor bottom panel shortcuts in the Editor Settings for inspiration. Per convention, they all use [kbd]Alt[/kbd] modifier. </description> </method> diff --git a/doc/classes/EditorProperty.xml b/doc/classes/EditorProperty.xml index 2b1083393f..4ff541f72d 100644 --- a/doc/classes/EditorProperty.xml +++ b/doc/classes/EditorProperty.xml @@ -132,6 +132,13 @@ Emitted when a property was deleted. Used internally. </description> </signal> + <signal name="property_favorited"> + <param index="0" name="property" type="StringName" /> + <param index="1" name="favorited" type="bool" /> + <description> + Emit it if you want to mark a property as favorited, making it appear at the top of the inspector. + </description> + </signal> <signal name="property_keyed"> <param index="0" name="property" type="StringName" /> <description> diff --git a/doc/classes/EditorResourcePreviewGenerator.xml b/doc/classes/EditorResourcePreviewGenerator.xml index 9c9b6d11b2..89bfe836d7 100644 --- a/doc/classes/EditorResourcePreviewGenerator.xml +++ b/doc/classes/EditorResourcePreviewGenerator.xml @@ -4,7 +4,7 @@ Custom generator of previews. </brief_description> <description> - Custom code to generate previews. Please check [code]file_dialog/thumbnail_size[/code] in [EditorSettings] to find out the right size to do previews at. + Custom code to generate previews. Check [member EditorSettings.filesystem/file_dialog/thumbnail_size] to find a proper size to generate previews at. </description> <tutorials> </tutorials> diff --git a/doc/classes/EditorScenePostImport.xml b/doc/classes/EditorScenePostImport.xml index 7325d31fc5..f8938c459c 100644 --- a/doc/classes/EditorScenePostImport.xml +++ b/doc/classes/EditorScenePostImport.xml @@ -5,7 +5,7 @@ </brief_description> <description> Imported scenes can be automatically modified right after import by setting their [b]Custom Script[/b] Import property to a [code]tool[/code] script that inherits from this class. - The [method _post_import] callback receives the imported scene's root node and returns the modified version of the scene. Usage example: + The [method _post_import] callback receives the imported scene's root node and returns the modified version of the scene: [codeblocks] [gdscript] @tool # Needed so it runs in editor. diff --git a/doc/classes/EditorScript.xml b/doc/classes/EditorScript.xml index bd18852dbc..e342966fe8 100644 --- a/doc/classes/EditorScript.xml +++ b/doc/classes/EditorScript.xml @@ -6,7 +6,7 @@ <description> Scripts extending this class and implementing its [method _run] method can be executed from the Script Editor's [b]File > Run[/b] menu option (or by pressing [kbd]Ctrl + Shift + X[/kbd]) while the editor is running. This is useful for adding custom in-editor functionality to Godot. For more complex additions, consider using [EditorPlugin]s instead. [b]Note:[/b] Extending scripts need to have [code]tool[/code] mode enabled. - [b]Example script:[/b] + [b]Example:[/b] Running the following script prints "Hello from the Godot Editor!": [codeblocks] [gdscript] @tool diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index ea5207e826..c35a376c85 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -359,7 +359,7 @@ <member name="editors/3d/navigation/navigation_scheme" type="int" setter="" getter=""> The navigation scheme preset to use in the 3D editor. Changing this setting will affect the mouse button and modifier controls used to navigate the 3D editor viewport. All schemes can use [kbd]Mouse wheel[/kbd] to zoom. - - [b]Godot:[/b] [kbd]Middle mouse button[/kbd] to orbit. [kbd]Shift + Middle mouse button[/kbd] to pan. [kbd]Ctrl + Shift + Middle mouse button[/kbd] to zoom. + - [b]Godot:[/b] [kbd]Middle mouse button[/kbd] to orbit. [kbd]Shift + Middle mouse button[/kbd] to pan. [kbd]Ctrl + Middle mouse button[/kbd] to zoom. - [b]Maya:[/b] [kbd]Alt + Left mouse button[/kbd] to orbit. [kbd]Middle mouse button[/kbd] to pan, [kbd]Shift + Middle mouse button[/kbd] to pan 10 times faster. [kbd]Alt + Right mouse button[/kbd] to zoom. - [b]Modo:[/b] [kbd]Alt + Left mouse button[/kbd] to orbit. [kbd]Alt + Shift + Left mouse button[/kbd] to pan. [kbd]Ctrl + Alt + Left mouse button[/kbd] to zoom. See also [member editors/3d/navigation/orbit_mouse_button], [member editors/3d/navigation/pan_mouse_button], [member editors/3d/navigation/zoom_mouse_button], and [member editors/3d/freelook/freelook_navigation_scheme]. @@ -1061,7 +1061,7 @@ Determines whether online features are enabled in the editor, such as the Asset Library or update checks. Disabling these online features helps alleviate privacy concerns by preventing the editor from making HTTP requests to the Godot website or third-party platforms hosting assets from the Asset Library. </member> <member name="network/debug/remote_host" type="String" setter="" getter=""> - The address to listen to when starting the remote debugger. This can be set to [code]0.0.0.0[/code] to allow external clients to connect to the remote debugger (instead of restricting the remote debugger to connections from [code]localhost[/code]). + The address to listen to when starting the remote debugger. This can be set to this device's local IP address to allow external clients to connect to the remote debugger (instead of restricting the remote debugger to connections from [code]localhost[/code]). </member> <member name="network/debug/remote_port" type="int" setter="" getter=""> The port to listen to when starting the remote debugger. Godot will try to use port numbers above the configured number if the configured number is already taken by another application. @@ -1091,9 +1091,11 @@ </member> <member name="run/bottom_panel/action_on_play" type="int" setter="" getter=""> The action to execute on the bottom panel when running the project. + [b]Note:[/b] This option won't do anything if the bottom panel switching is locked using the pin button in the corner of the bottom panel. </member> <member name="run/bottom_panel/action_on_stop" type="int" setter="" getter=""> The action to execute on the bottom panel when stopping the project. + [b]Note:[/b] This option won't do anything if the bottom panel switching is locked using the pin button in the corner of the bottom panel. </member> <member name="run/output/always_clear_output_on_play" type="bool" setter="" getter=""> If [code]true[/code], the editor will clear the Output panel when running the project. @@ -1326,6 +1328,9 @@ <member name="text_editor/script_list/group_help_pages" type="bool" setter="" getter=""> If [code]true[/code], class reference pages are grouped together at the bottom of the Script Editor's script list. </member> + <member name="text_editor/script_list/highlight_scene_scripts" type="bool" setter="" getter=""> + If [code]true[/code], the scripts that are used by the current scene are highlighted in the Script Editor's script list. + </member> <member name="text_editor/script_list/list_script_names_as" type="int" setter="" getter=""> Specifies how script paths should be displayed in Script Editor's script list. If using the "Name" option and some scripts share the same file name, more parts of their paths are revealed to avoid conflicts. </member> diff --git a/doc/classes/EditorToaster.xml b/doc/classes/EditorToaster.xml new file mode 100644 index 0000000000..c30b94c989 --- /dev/null +++ b/doc/classes/EditorToaster.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="EditorToaster" inherits="HBoxContainer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + Manages toast notifications within the editor. + </brief_description> + <description> + This object manages the functionality and display of toast notifications within the editor, ensuring timely and informative alerts are presented to users. + [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_editor_toaster]. + </description> + <tutorials> + </tutorials> + <methods> + <method name="push_toast"> + <return type="void" /> + <param index="0" name="message" type="String" /> + <param index="1" name="severity" type="int" enum="EditorToaster.Severity" default="0" /> + <param index="2" name="tooltip" type="String" default="""" /> + <description> + Pushes a toast notification to the editor for display. + </description> + </method> + </methods> + <constants> + <constant name="SEVERITY_INFO" value="0" enum="Severity"> + Toast will display with an INFO severity. + </constant> + <constant name="SEVERITY_WARNING" value="1" enum="Severity"> + Toast will display with a WARNING severity and have a corresponding color. + </constant> + <constant name="SEVERITY_ERROR" value="2" enum="Severity"> + Toast will display with an ERROR severity and have a corresponding color. + </constant> + </constants> +</class> diff --git a/doc/classes/EditorTranslationParserPlugin.xml b/doc/classes/EditorTranslationParserPlugin.xml index a47a41594e..43bbeaefa7 100644 --- a/doc/classes/EditorTranslationParserPlugin.xml +++ b/doc/classes/EditorTranslationParserPlugin.xml @@ -69,8 +69,7 @@ msgidsContextPlural.Add(new Godot.Collections.Array{"Only with context", "a friendly context", ""}); [/csharp] [/codeblocks] - [b]Note:[/b] If you override parsing logic for standard script types (GDScript, C#, etc.), it would be better to load the [code]path[/code] argument using [method ResourceLoader.load]. This is because built-in scripts are loaded as [Resource] type, not [FileAccess] type. - For example: + [b]Note:[/b] If you override parsing logic for standard script types (GDScript, C#, etc.), it would be better to load the [code]path[/code] argument using [method ResourceLoader.load]. This is because built-in scripts are loaded as [Resource] type, not [FileAccess] type. For example: [codeblocks] [gdscript] func _parse_file(path, msgids, msgids_context_plural): diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index 1779408a4d..47fc48305b 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -182,7 +182,8 @@ [b]Note:[/b] [member glow_map] has no effect when using the Compatibility rendering method, due to this rendering method using a simpler glow implementation optimized for low-end devices. </member> <member name="glow_map_strength" type="float" setter="set_glow_map_strength" getter="get_glow_map_strength" default="0.8"> - How strong of an impact the [member glow_map] should have on the overall glow effect. A strength of [code]0.0[/code] means the glow map has no effect on the overall glow effect. A strength of [code]1.0[/code] means the glow has a full effect on the overall glow effect (and can turn off glow entirely in specific areas of the screen if the glow map has black areas). + How strong of an influence the [member glow_map] should have on the overall glow effect. A strength of [code]0.0[/code] means the glow map has no influence, while a strength of [code]1.0[/code] means the glow map has full influence. + [b]Note:[/b] If the glow map has black areas, a value of [code]1.0[/code] can also turn off the glow effect entirely in specific areas of the screen. [b]Note:[/b] [member glow_map_strength] has no effect when using the Compatibility rendering method, due to this rendering method using a simpler glow implementation optimized for low-end devices. </member> <member name="glow_mix" type="float" setter="set_glow_mix" getter="get_glow_mix" default="0.05"> diff --git a/doc/classes/FileAccess.xml b/doc/classes/FileAccess.xml index 5888e30339..5c89b64429 100644 --- a/doc/classes/FileAccess.xml +++ b/doc/classes/FileAccess.xml @@ -34,7 +34,7 @@ [/codeblocks] In the example above, the file will be saved in the user data folder as specified in the [url=$DOCS_URL/tutorials/io/data_paths.html]Data paths[/url] documentation. [FileAccess] will close when it's freed, which happens when it goes out of scope or when it gets assigned with [code]null[/code]. [method close] can be used to close it before then explicitly. In C# the reference must be disposed manually, which can be done with the [code]using[/code] statement or by calling the [code]Dispose[/code] method directly. - [b]Note:[/b] To access project resources once exported, it is recommended to use [ResourceLoader] instead of [FileAccess], as some files are converted to engine-specific formats and their original source files might not be present in the exported PCK package. + [b]Note:[/b] To access project resources once exported, it is recommended to use [ResourceLoader] instead of [FileAccess], as some files are converted to engine-specific formats and their original source files might not be present in the exported PCK package. If using [FileAccess], make sure the file is included in the export by changing its import mode to [b]Keep File (exported as is)[/b] in the Import dock, or, for files where this option is not available, change the non-resource export filter in the Export dialog to include the file's extension (e.g. [code]*.txt[/code]). [b]Note:[/b] Files are automatically closed only if the process exits "normally" (such as by clicking the window manager's close button or pressing [b]Alt + F4[/b]). If you stop the project execution by pressing [b]F8[/b] while the project is running, the file won't be closed as the game process will be killed. You can work around this by calling [method flush] at regular intervals. </description> <tutorials> @@ -308,6 +308,7 @@ <param index="0" name="path" type="String" /> <param index="1" name="mode_flags" type="int" enum="FileAccess.ModeFlags" /> <param index="2" name="key" type="PackedByteArray" /> + <param index="3" name="iv" type="PackedByteArray" default="PackedByteArray()" /> <description> Creates a new [FileAccess] object and opens an encrypted file in write or read mode. You need to pass a binary key to encrypt/decrypt it. [b]Note:[/b] The provided key must be 32 bytes long. diff --git a/doc/classes/GPUParticles2D.xml b/doc/classes/GPUParticles2D.xml index 3c48f5ba31..96232f4277 100644 --- a/doc/classes/GPUParticles2D.xml +++ b/doc/classes/GPUParticles2D.xml @@ -136,7 +136,7 @@ <signal name="finished"> <description> Emitted when all active particles have finished processing. To immediately restart the emission cycle, call [method restart]. - Never emitted when [member one_shot] is disabled, as particles will be emitted and processed continuously. + This signal is never emitted when [member one_shot] is disabled, as particles will be emitted and processed continuously. [b]Note:[/b] For [member one_shot] emitters, due to the particles being computed on the GPU, there may be a short period after receiving the signal during which setting [member emitting] to [code]true[/code] will not restart the emission cycle. This delay is avoided by instead calling [method restart]. </description> </signal> diff --git a/doc/classes/GPUParticles3D.xml b/doc/classes/GPUParticles3D.xml index 61a3b467f1..f5df857391 100644 --- a/doc/classes/GPUParticles3D.xml +++ b/doc/classes/GPUParticles3D.xml @@ -160,8 +160,8 @@ <signals> <signal name="finished"> <description> - Emitted when all active particles have finished processing. To immediately emit new particles, call [method restart]. - Never emitted when [member one_shot] is disabled, as particles will be emitted and processed continuously. + Emitted when all active particles have finished processing. To immediately restart the emission cycle, call [method restart]. + This signal is never emitted when [member one_shot] is disabled, as particles will be emitted and processed continuously. [b]Note:[/b] For [member one_shot] emitters, due to the particles being computed on the GPU, there may be a short period after receiving the signal during which setting [member emitting] to [code]true[/code] will not restart the emission cycle. This delay is avoided by instead calling [method restart]. </description> </signal> diff --git a/doc/classes/GPUParticlesCollision3D.xml b/doc/classes/GPUParticlesCollision3D.xml index 089747b7ee..2d398edd5e 100644 --- a/doc/classes/GPUParticlesCollision3D.xml +++ b/doc/classes/GPUParticlesCollision3D.xml @@ -16,8 +16,8 @@ <members> <member name="cull_mask" type="int" setter="set_cull_mask" getter="get_cull_mask" default="4294967295"> The particle rendering layers ([member VisualInstance3D.layers]) that will be affected by the collision shape. By default, all particles that have [member ParticleProcessMaterial.collision_mode] set to [constant ParticleProcessMaterial.COLLISION_RIGID] or [constant ParticleProcessMaterial.COLLISION_HIDE_ON_CONTACT] will be affected by a collision shape. - After configuring particle nodes accordingly, specific layers can be unchecked to prevent certain particles from being affected by attractors. For example, this can be used if you're using an attractor as part of a spell effect but don't want the attractor to affect unrelated weather particles at the same position. - Particle attraction can also be disabled on a per-process material basis by setting [member ParticleProcessMaterial.attractor_interaction_enabled] on the [GPUParticles3D] node. + After configuring particle nodes accordingly, specific layers can be unchecked to prevent certain particles from being affected by colliders. For example, this can be used if you're using a collider as part of a spell effect but don't want the collider to affect unrelated weather particles at the same position. + Particle collision can also be disabled on a per-process material basis by setting [member ParticleProcessMaterial.collision_mode] on the [GPUParticles3D] node. </member> </members> </class> diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml index af98636056..366038e43f 100644 --- a/doc/classes/HTTPClient.xml +++ b/doc/classes/HTTPClient.xml @@ -277,7 +277,11 @@ HTTP status code [code]102 Processing[/code] (WebDAV). Indicates that the server has received and is processing the request, but no response is available yet. </constant> <constant name="RESPONSE_OK" value="200" enum="ResponseCode"> - HTTP status code [code]200 OK[/code]. The request has succeeded. Default response for successful requests. Meaning varies depending on the request. GET: The resource has been fetched and is transmitted in the message body. HEAD: The entity headers are in the message body. POST: The resource describing the result of the action is transmitted in the message body. TRACE: The message body contains the request message as received by the server. + HTTP status code [code]200 OK[/code]. The request has succeeded. Default response for successful requests. Meaning varies depending on the request: + - [constant METHOD_GET]: The resource has been fetched and is transmitted in the message body. + - [constant METHOD_HEAD]: The entity headers are in the message body. + - [constant METHOD_POST]: The resource describing the result of the action is transmitted in the message body. + - [constant METHOD_TRACE]: The message body contains the request message as received by the server. </constant> <constant name="RESPONSE_CREATED" value="201" enum="ResponseCode"> HTTP status code [code]201 Created[/code]. The request has succeeded and a new resource has been created as a result of it. This is typically the response sent after a PUT request. diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml index a4adf4d1b1..36f5e82652 100644 --- a/doc/classes/HTTPRequest.xml +++ b/doc/classes/HTTPRequest.xml @@ -8,7 +8,7 @@ Can be used to make HTTP requests, i.e. download or upload files or web content via HTTP. [b]Warning:[/b] See the notes and warnings on [HTTPClient] for limitations, especially regarding TLS security. [b]Note:[/b] When exporting to Android, make sure to enable the [code]INTERNET[/code] permission in the Android export preset before exporting the project or using one-click deploy. Otherwise, network communication of any kind will be blocked by Android. - [b]Example of contacting a REST API and printing one of its returned fields:[/b] + [b]Example:[/b] Contact a REST API and print one of its returned fields: [codeblocks] [gdscript] func _ready(): @@ -80,7 +80,7 @@ } [/csharp] [/codeblocks] - [b]Example of loading and displaying an image using HTTPRequest:[/b] + [b]Example:[/b] Load an image using [HTTPRequest] and display it: [codeblocks] [gdscript] func _ready(): @@ -150,7 +150,7 @@ } [/csharp] [/codeblocks] - [b]Gzipped response bodies[/b]: HTTPRequest will automatically handle decompression of response bodies. A [code]Accept-Encoding[/code] header will be automatically added to each of your requests, unless one is already specified. Any response with a [code]Content-Encoding: gzip[/code] header will automatically be decompressed and delivered to you as uncompressed bytes. + [b]Note:[/b] [HTTPRequest] nodes will automatically handle decompression of response bodies. A [code]Accept-Encoding[/code] header will be automatically added to each of your requests, unless one is already specified. Any response with a [code]Content-Encoding: gzip[/code] header will automatically be decompressed and delivered to you as uncompressed bytes. </description> <tutorials> <link title="Making HTTP requests">$DOCS_URL/tutorials/networking/http_request_class.html</link> diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index 9b71a8c37f..4421318be7 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -48,6 +48,7 @@ <param index="2" name="dst" type="Vector2i" /> <description> Copies [param src_rect] from [param src] image to this image at coordinates [param dst], clipped accordingly to both image bounds. This image and [param src] image [b]must[/b] have the same format. [param src_rect] with non-positive size is treated as empty. + [b]Note:[/b] The alpha channel data in [param src] will overwrite the corresponding data in this image at the target position. To blend alpha channels, use [method blend_rect] instead. </description> </method> <method name="blit_rect_mask"> diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml index fdaeb54bdf..7754a61e8c 100644 --- a/doc/classes/ItemList.xml +++ b/doc/classes/ItemList.xml @@ -29,7 +29,7 @@ <description> Adds an item to the item list with specified text. Returns the index of an added item. Specify an [param icon], or use [code]null[/code] as the [param icon] for a list item with no icon. - If selectable is [code]true[/code], the list item will be selectable. + If [param selectable] is [code]true[/code], the list item will be selectable. </description> </method> <method name="clear"> diff --git a/doc/classes/LightmapGI.xml b/doc/classes/LightmapGI.xml index e7d44411ef..139bf6e4d1 100644 --- a/doc/classes/LightmapGI.xml +++ b/doc/classes/LightmapGI.xml @@ -66,7 +66,7 @@ </member> <member name="quality" type="int" setter="set_bake_quality" getter="get_bake_quality" enum="LightmapGI.BakeQuality" default="1"> The quality preset to use when baking lightmaps. This affects bake times, but output file sizes remain mostly identical across quality levels. - To further speed up bake times, decrease [member bounces], disable [member use_denoiser] and increase the lightmap texel size on 3D scenes in the Import doc. + To further speed up bake times, decrease [member bounces], disable [member use_denoiser] and increase the lightmap texel size on 3D scenes in the Import dock. </member> <member name="texel_scale" type="float" setter="set_texel_scale" getter="get_texel_scale" default="1.0"> Scales the lightmap texel density of all meshes for the current bake. This is a multiplier that builds upon the existing lightmap texel size defined in each imported 3D scene, along with the per-mesh density multiplier (which is designed to be used when the same mesh is used at different scales). Lower values will result in faster bake times. diff --git a/doc/classes/LookAtModifier3D.xml b/doc/classes/LookAtModifier3D.xml new file mode 100644 index 0000000000..e85da06c3a --- /dev/null +++ b/doc/classes/LookAtModifier3D.xml @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="LookAtModifier3D" inherits="SkeletonModifier3D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + The [SkeletonModifier3D] rotates a bone to look a target. + </brief_description> + <description> + This [SkeletonModifier3D] rotates a bone to look a target. This is helpful for moving character's head to look at the player, rotating a turret to look at a target, or any other case where you want to make a bone rotate towards something quickly and easily. + When applying multiple [LookAtModifier3D]s, the [LookAtModifier3D] assigned to the parent bone must be put above the [LookAtModifier3D] assigned to the child bone in the list in order for the child bone results to be correct. + </description> + <tutorials> + </tutorials> + <methods> + <method name="get_interpolation_remaining" qualifiers="const"> + <return type="float" /> + <description> + Returns the remaining seconds of the time-based interpolation. + </description> + </method> + <method name="is_interpolating" qualifiers="const"> + <return type="bool" /> + <description> + Returns whether the time-based interpolation is running or not. If [code]true[/code], it is equivalent to [method get_interpolation_remaining] being [code]0[/code]. + This is useful to determine whether a [LookAtModifier3D] can be removed safely. + </description> + </method> + <method name="is_target_within_limitation" qualifiers="const"> + <return type="bool" /> + <description> + Returns whether the target is within the angle limitations. It is useful for unsetting the [member target_node] when the target is outside of the angle limitations. + [b]Note:[/b] The value is updated after [method SkeletonModifier3D._process_modification]. To retrieve this value correctly, we recommend using the signal [signal SkeletonModifier3D.modification_processed]. + </description> + </method> + </methods> + <members> + <member name="bone" type="int" setter="set_bone" getter="get_bone" default="0"> + The bone index of the [Skeleton3D] that the modification will operate on. + </member> + <member name="duration" type="float" setter="set_duration" getter="get_duration" default="0.0"> + The duration of the time-based interpolation. Interpolation is triggered at the following cases: + - When the target node is changed + - When an axis is flipped due to angle limitation + [b]Note:[/b] The flipping occurs when the target is outside the angle limitation and the internally computed secondary rotation axis of the forward vector is flipped. Visually, it occurs when the target is outside the angle limitation and crosses the plane of the [member forward_axis] and [member primary_rotation_axis]. + </member> + <member name="ease_type" type="int" setter="set_ease_type" getter="get_ease_type" enum="Tween.EaseType" default="0"> + The ease type of the time-based interpolation. See also [enum Tween.EaseType]. + </member> + <member name="forward_axis" type="int" setter="set_forward_axis" getter="get_forward_axis" enum="LookAtModifier3D.BoneAxis" default="4"> + The forward axis of the bone. This [SkeletonModifier3D] modifies the bone so that this axis points toward the [member target_node]. + </member> + <member name="origin_bone" type="int" setter="set_origin_bone" getter="get_origin_bone"> + If [member origin_from] is [constant ORIGIN_FROM_SPECIFIC_BONE], the bone global pose position specified for this is used as origin. + </member> + <member name="origin_external_node" type="NodePath" setter="set_origin_external_node" getter="get_origin_external_node"> + If [member origin_from] is [constant ORIGIN_FROM_EXTERNAL_NODE], the global position of the [Node3D] specified for this is used as origin. + </member> + <member name="origin_from" type="int" setter="set_origin_from" getter="get_origin_from" enum="LookAtModifier3D.OriginFrom" default="0"> + This value determines from what origin is retrieved for use in the calculation of the forward vector. + </member> + <member name="origin_offset" type="Vector3" setter="set_origin_offset" getter="get_origin_offset" default="Vector3(0, 0, 0)"> + The offset of the bone pose origin. Matching the origins by offset is useful for cases where multiple bones must always face the same direction, such as the eyes. + [b]Note:[/b] This value indicates the local position of the object set in [member origin_from]. + </member> + <member name="origin_safe_margin" type="float" setter="set_origin_safe_margin" getter="get_origin_safe_margin" default="0.1"> + If the target passes through too close to the origin than this value, time-based interpolation is used even if the target is within the angular limitations, to prevent the angular velocity from becoming too high. + </member> + <member name="primary_damp_threshold" type="float" setter="set_primary_damp_threshold" getter="get_primary_damp_threshold"> + The threshold to start damping for [member primary_limit_angle]. It provides non-linear (b-spline) interpolation, let it feel more resistance the more it rotate to the edge limit. This is useful for simulating the limits of human motion. + If [code]1.0[/code], no damping is performed. If [code]0.0[/code], damping is always performed. + </member> + <member name="primary_limit_angle" type="float" setter="set_primary_limit_angle" getter="get_primary_limit_angle"> + The limit angle of the primary rotation when [member symmetry_limitation] is [code]true[/code]. + </member> + <member name="primary_negative_damp_threshold" type="float" setter="set_primary_negative_damp_threshold" getter="get_primary_negative_damp_threshold"> + The threshold to start damping for [member primary_negative_limit_angle]. + </member> + <member name="primary_negative_limit_angle" type="float" setter="set_primary_negative_limit_angle" getter="get_primary_negative_limit_angle"> + The limit angle of negative side of the primary rotation when [member symmetry_limitation] is [code]false[/code]. + </member> + <member name="primary_positive_damp_threshold" type="float" setter="set_primary_positive_damp_threshold" getter="get_primary_positive_damp_threshold"> + The threshold to start damping for [member primary_positive_limit_angle]. + </member> + <member name="primary_positive_limit_angle" type="float" setter="set_primary_positive_limit_angle" getter="get_primary_positive_limit_angle"> + The limit angle of positive side of the primary rotation when [member symmetry_limitation] is [code]false[/code]. + </member> + <member name="primary_rotation_axis" type="int" setter="set_primary_rotation_axis" getter="get_primary_rotation_axis" enum="Vector3.Axis" default="1"> + The axis of the first rotation. This [SkeletonModifier3D] works by compositing the rotation by Euler angles to prevent to rotate the [member forward_axis]. + </member> + <member name="secondary_damp_threshold" type="float" setter="set_secondary_damp_threshold" getter="get_secondary_damp_threshold"> + The threshold to start damping for [member secondary_limit_angle]. + </member> + <member name="secondary_limit_angle" type="float" setter="set_secondary_limit_angle" getter="get_secondary_limit_angle"> + The limit angle of the secondary rotation when [member symmetry_limitation] is [code]true[/code]. + </member> + <member name="secondary_negative_damp_threshold" type="float" setter="set_secondary_negative_damp_threshold" getter="get_secondary_negative_damp_threshold"> + The threshold to start damping for [member secondary_negative_limit_angle]. + </member> + <member name="secondary_negative_limit_angle" type="float" setter="set_secondary_negative_limit_angle" getter="get_secondary_negative_limit_angle"> + The limit angle of negative side of the secondary rotation when [member symmetry_limitation] is [code]false[/code]. + </member> + <member name="secondary_positive_damp_threshold" type="float" setter="set_secondary_positive_damp_threshold" getter="get_secondary_positive_damp_threshold"> + The threshold to start damping for [member secondary_positive_limit_angle]. + </member> + <member name="secondary_positive_limit_angle" type="float" setter="set_secondary_positive_limit_angle" getter="get_secondary_positive_limit_angle"> + The limit angle of positive side of the secondary rotation when [member symmetry_limitation] is [code]false[/code]. + </member> + <member name="symmetry_limitation" type="bool" setter="set_symmetry_limitation" getter="is_limitation_symmetry"> + If [code]true[/code], the limitations are spread from the bone symmetrically. + If [code]false[/code], the limitation can be specified separately for each side of the bone rest. + </member> + <member name="target_node" type="NodePath" setter="set_target_node" getter="get_target_node" default="NodePath("")"> + The [NodePath] to the node that is the target for the look at modification. This node is what the modification will rotate the bone to. + </member> + <member name="transition_type" type="int" setter="set_transition_type" getter="get_transition_type" enum="Tween.TransitionType" default="0"> + The transition type of the time-based interpolation. See also [enum Tween.TransitionType]. + </member> + <member name="use_angle_limitation" type="bool" setter="set_use_angle_limitation" getter="is_using_angle_limitation" default="false"> + If [code]true[/code], limits the degree of rotation. This helps prevent the character's neck from rotating 360 degrees. + [b]Note:[/b] As with [AnimationTree] blending, interpolation is provided that favors [method Skeleton3D.get_bone_rest]. This means that interpolation does not select the shortest path in some cases. + [b]Note:[/b] Some [member transition_type] may exceed the limitations (e.g. `Back`, `Elastic`, and `Spring`). If interpolation occurs while overshooting the limitations, the result might possibly not respect the bone rest. + </member> + <member name="use_secondary_rotation" type="bool" setter="set_use_secondary_rotation" getter="is_using_secondary_rotation" default="true"> + If [code]true[/code], provides rotation by two axes. + </member> + </members> + <constants> + <constant name="BONE_AXIS_PLUS_X" value="0" enum="BoneAxis"> + Enumerated value for the +X axis. + </constant> + <constant name="BONE_AXIS_MINUS_X" value="1" enum="BoneAxis"> + Enumerated value for the -X axis. + </constant> + <constant name="BONE_AXIS_PLUS_Y" value="2" enum="BoneAxis"> + Enumerated value for the +Y axis. + </constant> + <constant name="BONE_AXIS_MINUS_Y" value="3" enum="BoneAxis"> + Enumerated value for the -Y axis. + </constant> + <constant name="BONE_AXIS_PLUS_Z" value="4" enum="BoneAxis"> + Enumerated value for the +Z axis. + </constant> + <constant name="BONE_AXIS_MINUS_Z" value="5" enum="BoneAxis"> + Enumerated value for the -Z axis. + </constant> + <constant name="ORIGIN_FROM_SELF" value="0" enum="OriginFrom"> + The bone rest position of the bone specified in [member bone] is used as origin. + </constant> + <constant name="ORIGIN_FROM_SPECIFIC_BONE" value="1" enum="OriginFrom"> + The bone global pose position of the bone specified in [member origin_bone] is used as origin. + [b]Note:[/b] It is recommended that you select only the parent bone unless you are familiar with the bone processing process. The specified bone pose at the time the [LookAtModifier3D] is processed is used as a reference. In other words, if you specify a child bone and the [LookAtModifier3D] causes the child bone to move, the rendered result and direction will not match. + </constant> + <constant name="ORIGIN_FROM_EXTERNAL_NODE" value="2" enum="OriginFrom"> + The global position of the [Node3D] specified in [member origin_external_node] is used as origin. + [b]Note:[/b] Same as [constant ORIGIN_FROM_SPECIFIC_BONE], when specifying a [BoneAttachment3D] with a child bone assigned, the rendered result and direction will not match. + </constant> + </constants> +</class> diff --git a/doc/classes/MainLoop.xml b/doc/classes/MainLoop.xml index 17cc0d78d3..2d88876d24 100644 --- a/doc/classes/MainLoop.xml +++ b/doc/classes/MainLoop.xml @@ -5,7 +5,7 @@ </brief_description> <description> [MainLoop] is the abstract base class for a Godot project's game loop. It is inherited by [SceneTree], which is the default game loop implementation used in Godot projects, though it is also possible to write and use one's own [MainLoop] subclass instead of the scene tree. - Upon the application start, a [MainLoop] implementation must be provided to the OS; otherwise, the application will exit. This happens automatically (and a [SceneTree] is created) unless a [MainLoop] [Script] is provided from the command line (with e.g. [code]godot -s my_loop.gd[/code]) or the "Main Loop Type" project setting is overwritten. + Upon the application start, a [MainLoop] implementation must be provided to the OS; otherwise, the application will exit. This happens automatically (and a [SceneTree] is created) unless a [MainLoop] [Script] is provided from the command line (with e.g. [code]godot -s my_loop.gd[/code]) or the [member ProjectSettings.application/run/main_loop_type] project setting is overwritten. Here is an example script implementing a simple [MainLoop]: [codeblocks] [gdscript] diff --git a/doc/classes/MeshInstance3D.xml b/doc/classes/MeshInstance3D.xml index d8e2c43566..a0a773b90a 100644 --- a/doc/classes/MeshInstance3D.xml +++ b/doc/classes/MeshInstance3D.xml @@ -120,7 +120,7 @@ <param index="1" name="material" type="Material" /> <description> Sets the override [param material] for the specified [param surface] of the [Mesh] resource. This material is associated with this [MeshInstance3D] rather than with [member mesh]. - [b]Note:[/b] This assigns the [Material] associated to the [MeshInstance3D]'s Surface Material Override properties, not the material within the [Mesh] resource. To set the material within the [Mesh] resource, use [method Mesh.surface_get_material] instead. + [b]Note:[/b] This assigns the [Material] associated to the [MeshInstance3D]'s Surface Material Override properties, not the material within the [Mesh] resource. To set the material within the [Mesh] resource, use [method Mesh.surface_set_material] instead. </description> </method> </methods> diff --git a/doc/classes/MultiplayerAPI.xml b/doc/classes/MultiplayerAPI.xml index d5016867a7..75cb13d25d 100644 --- a/doc/classes/MultiplayerAPI.xml +++ b/doc/classes/MultiplayerAPI.xml @@ -88,7 +88,7 @@ <param index="3" name="arguments" type="Array" default="[]" /> <description> Sends an RPC to the target [param peer]. The given [param method] will be called on the remote [param object] with the provided [param arguments]. The RPC may also be called locally depending on the implementation and RPC configuration. See [method Node.rpc] and [method Node.rpc_config]. - [b]Note:[/b] Prefer using [method Node.rpc], [method Node.rpc_id], or [code]my_method.rpc(peer, arg1, arg2, ...)[/code] (in GDScript), since they are faster. This method is mostly useful in conjunction with [MultiplayerAPIExtension] when augmenting or replacing the multiplayer capabilities. + [b]Note:[/b] Prefer using [method Node.rpc], [method Node.rpc_id], or [code]my_method.rpc(peer, arg1, arg2, ...)[/code] (in GDScript), since they are faster. This method is mostly useful in conjunction with [MultiplayerAPIExtension] when extending or replacing the multiplayer capabilities. </description> </method> <method name="set_default_interface" qualifiers="static"> diff --git a/doc/classes/MultiplayerAPIExtension.xml b/doc/classes/MultiplayerAPIExtension.xml index cc6d3b7fcf..acb6a2c176 100644 --- a/doc/classes/MultiplayerAPIExtension.xml +++ b/doc/classes/MultiplayerAPIExtension.xml @@ -4,14 +4,14 @@ Base class used for extending the [MultiplayerAPI]. </brief_description> <description> - This class can be used to augment or replace the default [MultiplayerAPI] implementation via script or extensions. - The following example augment the default implementation ([SceneMultiplayer]) by logging every RPC being made, and every object being configured for replication. + This class can be used to extend or replace the default [MultiplayerAPI] implementation via script or extensions. + The following example extend the default implementation ([SceneMultiplayer]) by logging every RPC being made, and every object being configured for replication. [codeblocks] [gdscript] extends MultiplayerAPIExtension class_name LogMultiplayer - # We want to augment the default SceneMultiplayer. + # We want to extend the default SceneMultiplayer. var base_multiplayer = SceneMultiplayer.new() func _init(): @@ -49,7 +49,7 @@ print("Removing node %s from the spawn list. Spawner: %s" % [object, config]) return base_multiplayer.object_configuration_remove(object, config) - # These can be optional, but in our case we want to augment SceneMultiplayer, so forward everything. + # These can be optional, but in our case we want to extend SceneMultiplayer, so forward everything. func _set_multiplayer_peer(p_peer: MultiplayerPeer): base_multiplayer.multiplayer_peer = p_peer @@ -69,7 +69,7 @@ # autoload.gd func _enter_tree(): # Sets our custom multiplayer as the main one in SceneTree. - get_tree().set_multiplayer(LogMultiplayer.new()) + get_tree().set_multiplayer(LogMultiplayer.new()) [/gdscript] [/codeblocks] Native extensions can alternatively use the [method MultiplayerAPI.set_default_interface] method during initialization to configure themselves as the default implementation. diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index c07948b546..3cb76e2926 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -1006,8 +1006,8 @@ [b]Note:[/b] When changing the name, the following characters will be replaced with an underscore: ([code].[/code] [code]:[/code] [code]@[/code] [code]/[/code] [code]"[/code] [code]%[/code]). In particular, the [code]@[/code] character is reserved for auto-generated names. See also [method String.validate_node_name]. </member> <member name="owner" type="Node" setter="set_owner" getter="get_owner"> - The owner of this node. The owner must be an ancestor of this node. When packing the owner node in a [PackedScene], all the nodes it owns are also saved with it. - [b]Note:[/b] In the editor, nodes not owned by the scene root are usually not displayed in the Scene dock, and will [b]not[/b] be saved. To prevent this, remember to set the owner after calling [method add_child]. See also (see [member unique_name_in_owner]) + The owner of this node. The owner must be an ancestor of this node. When packing the owner node in a [PackedScene], all the nodes it owns are also saved with it. See also [member unique_name_in_owner]. + [b]Note:[/b] In the editor, nodes not owned by the scene root are usually not displayed in the Scene dock, and will [b]not[/b] be saved. To prevent this, remember to set the owner after calling [method add_child]. </member> <member name="physics_interpolation_mode" type="int" setter="set_physics_interpolation_mode" getter="get_physics_interpolation_mode" enum="Node.PhysicsInterpolationMode" default="0"> Allows enabling or disabling physics interpolation per node, offering a finer grain of control than turning physics interpolation on and off globally. See [member ProjectSettings.physics/common/physics_interpolation] and [member SceneTree.physics_interpolation] for the global setting. diff --git a/doc/classes/NodePath.xml b/doc/classes/NodePath.xml index d0ec81ab45..628c7106f2 100644 --- a/doc/classes/NodePath.xml +++ b/doc/classes/NodePath.xml @@ -57,7 +57,7 @@ <description> Constructs a [NodePath] from a [String]. The created path is absolute if prefixed with a slash (see [method is_absolute]). The "subnames" optionally included after the path to the target node can point to properties, and can also be nested. - Examples of strings that could be node paths: + The following strings can be valid node paths: [codeblock] # Points to the Sprite2D node. "Level/RigidBody2D/Sprite2D" diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index 777950c075..5ab7c27f4f 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -23,7 +23,7 @@ <return type="void" /> <description> Shuts down the system MIDI driver. Godot will no longer receive [InputEventMIDI]. See also [method open_midi_inputs] and [method get_connected_midi_inputs]. - [b]Note:[/b] This method is implemented on Linux, macOS and Windows. + [b]Note:[/b] This method is implemented on Linux, macOS, and Windows. </description> </method> <method name="crash"> @@ -53,7 +53,7 @@ Creates a new process that runs independently of Godot. It will not terminate when Godot terminates. The path specified in [param path] must exist and be an executable file or macOS [code].app[/code] bundle. The path is resolved based on the current platform. The [param arguments] are used in the given order and separated by a space. On Windows, if [param open_console] is [code]true[/code] and the process is a console app, a new terminal window will be opened. If the process is successfully created, this method returns its process ID, which you can use to monitor the process (and potentially terminate it with [method kill]). Otherwise, this method returns [code]-1[/code]. - For example, running another instance of the project: + [b]Example:[/b] Run another instance of the project: [codeblocks] [gdscript] var pid = OS.create_process(OS.get_executable_path(), []) @@ -184,7 +184,7 @@ Command-line arguments can be written in any form, including both [code]--key value[/code] and [code]--key=value[/code] forms so they can be properly parsed, as long as custom command-line arguments do not conflict with engine arguments. You can also incorporate environment variables using the [method get_environment] method. You can set [member ProjectSettings.editor/run/main_run_args] to define command-line arguments to be passed by the editor when running the project. - Here's a minimal example on how to parse command-line arguments into a [Dictionary] using the [code]--key=value[/code] form for arguments: + [b]Example:[/b] Parse command-line arguments into a [Dictionary] using the [code]--key=value[/code] form for arguments: [codeblocks] [gdscript] var arguments = {} @@ -244,7 +244,7 @@ <return type="PackedStringArray" /> <description> Returns an array of connected MIDI device names, if they exist. Returns an empty array if the system MIDI driver has not previously been initialized with [method open_midi_inputs]. See also [method close_midi_inputs]. - [b]Note:[/b] This method is implemented on Linux, macOS and Windows. + [b]Note:[/b] This method is implemented on Linux, macOS, and Windows. </description> </method> <method name="get_data_dir" qualifiers="const"> @@ -356,7 +356,7 @@ <return type="String" /> <description> Returns the model name of the current device. - [b]Note:[/b] This method is implemented on Android and iOS. Returns [code]"GenericDevice"[/code] on unsupported platforms. + [b]Note:[/b] This method is implemented on Android, iOS, macOS, and Windows. Returns [code]"GenericDevice"[/code] on unsupported platforms. </description> </method> <method name="get_name" qualifiers="const"> @@ -466,6 +466,24 @@ Returns the amount of static memory being used by the program in bytes. Only works in debug builds. </description> </method> + <method name="get_stderr_type" qualifiers="const"> + <return type="int" enum="OS.StdHandleType" /> + <description> + Returns type of the standard error device. + </description> + </method> + <method name="get_stdin_type" qualifiers="const"> + <return type="int" enum="OS.StdHandleType" /> + <description> + Returns type of the standard input device. + </description> + </method> + <method name="get_stdout_type" qualifiers="const"> + <return type="int" enum="OS.StdHandleType" /> + <description> + Returns type of the standard output device. + </description> + </method> <method name="get_system_ca_certificates"> <return type="String" /> <description> @@ -680,15 +698,31 @@ <return type="void" /> <description> Initializes the singleton for the system MIDI driver, allowing Godot to receive [InputEventMIDI]. See also [method get_connected_midi_inputs] and [method close_midi_inputs]. - [b]Note:[/b] This method is implemented on Linux, macOS and Windows. + [b]Note:[/b] This method is implemented on Linux, macOS, and Windows. + </description> + </method> + <method name="read_buffer_from_stdin"> + <return type="PackedByteArray" /> + <param index="0" name="buffer_size" type="int" /> + <description> + Reads a user input as raw data from the standard input. This operation can be [i]blocking[/i], which causes the window to freeze if [method read_string_from_stdin] is called on the main thread. + - If standard input is console, this method will block until the program receives a line break in standard input (usually by the user pressing [kbd]Enter[/kbd]). + - If standard input is pipe, this method will block until a specific amount of data is read or pipe is closed. + - If standard input is a file, this method will read a specific amount of data (or less if end-of-file is reached) and return immediately. + [b]Note:[/b] This method is implemented on Linux, macOS, and Windows. + [b]Note:[/b] On exported Windows builds, run the console wrapper executable to access the terminal. If standard input is console, calling this method without console wrapped will freeze permanently. If standard input is pipe or file, it can be used without console wrapper. If you need a single executable with full console support, use a custom build compiled with the [code]windows_subsystem=console[/code] flag. </description> </method> <method name="read_string_from_stdin"> <return type="String" /> + <param index="0" name="buffer_size" type="int" /> <description> - Reads a user input string from the standard input (usually the terminal). This operation is [i]blocking[/i], which causes the window to freeze if [method read_string_from_stdin] is called on the main thread. The thread calling [method read_string_from_stdin] will block until the program receives a line break in standard input (usually by the user pressing [kbd]Enter[/kbd]). - [b]Note:[/b] This method is implemented on Linux, macOS and Windows. - [b]Note:[/b] On exported Windows builds, run the console wrapper executable to access the terminal. Otherwise, the standard input will not work correctly. If you need a single executable with console support, use a custom build compiled with the [code]windows_subsystem=console[/code] flag. + Reads a user input as a UTF-8 encoded string from the standard input. This operation can be [i]blocking[/i], which causes the window to freeze if [method read_string_from_stdin] is called on the main thread. + - If standard input is console, this method will block until the program receives a line break in standard input (usually by the user pressing [kbd]Enter[/kbd]). + - If standard input is pipe, this method will block until a specific amount of data is read or pipe is closed. + - If standard input is a file, this method will read a specific amount of data (or less if end-of-file is reached) and return immediately. + [b]Note:[/b] This method is implemented on Linux, macOS, and Windows. + [b]Note:[/b] On exported Windows builds, run the console wrapper executable to access the terminal. If standard input is console, calling this method without console wrapped will freeze permanently. If standard input is pipe or file, it can be used without console wrapper. If you need a single executable with full console support, use a custom build compiled with the [code]windows_subsystem=console[/code] flag. </description> </method> <method name="request_permission"> @@ -831,5 +865,20 @@ <constant name="SYSTEM_DIR_RINGTONES" value="7" enum="SystemDir"> Refers to the Ringtones directory path. </constant> + <constant name="STD_HANDLE_INVALID" value="0" enum="StdHandleType"> + Standard I/O device is invalid. No data can be received from or sent to these standard I/O devices. + </constant> + <constant name="STD_HANDLE_CONSOLE" value="1" enum="StdHandleType"> + Standard I/O device is a console. This typically occurs when Godot is run from a terminal with no redirection. This is also used for all standard I/O devices when running Godot from the editor, at least on desktop platforms. + </constant> + <constant name="STD_HANDLE_FILE" value="2" enum="StdHandleType"> + Standard I/O device is a regular file. This typically occurs with redirection from a terminal, e.g. [code]godot > stdout.txt[/code], [code]godot < stdin.txt[/code] or [code]godot > stdout_stderr.txt 2>&1[/code]. + </constant> + <constant name="STD_HANDLE_PIPE" value="3" enum="StdHandleType"> + Standard I/O device is a FIFO/pipe. This typically occurs with pipe usage from a terminal, e.g. [code]echo "Hello" | godot[/code]. + </constant> + <constant name="STD_HANDLE_UNKNOWN" value="4" enum="StdHandleType"> + Standard I/O device type is unknown. + </constant> </constants> </class> diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index a130a71826..d0c193ea31 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -343,7 +343,7 @@ return "Welcome to Godot 4!" func _init(): - print(self) # Prints Welcome to Godot 4!" + print(self) # Prints "Welcome to Godot 4!" var a = str(self) # a is "Welcome to Godot 4!" [/codeblock] </description> @@ -406,7 +406,7 @@ <param index="0" name="signal" type="String" /> <param index="1" name="arguments" type="Array" default="[]" /> <description> - Adds a user-defined [param signal]. Optional arguments for the signal can be added as an [Array] of dictionaries, each defining a [code]name[/code] [String] and a [code]type[/code] [int] (see [enum Variant.Type]). See also [method has_user_signal] and [method remove_user_signal]. + Adds a user-defined signal named [param signal]. Optional arguments for the signal can be added as an [Array] of dictionaries, each defining a [code]name[/code] [String] and a [code]type[/code] [int] (see [enum Variant.Type]). See also [method has_user_signal] and [method remove_user_signal]. [codeblocks] [gdscript] add_user_signal("hurt", [ @@ -854,7 +854,7 @@ <param index="0" name="signal" type="StringName" /> <description> Returns [code]true[/code] if the given [param signal] name exists in the object. - [b]Note:[/b] In C#, [param signal] must be in snake_case when referring to built-in Godot methods. Prefer using the names exposed in the [code]SignalName[/code] class to avoid allocating a new [StringName] on each call. + [b]Note:[/b] In C#, [param signal] must be in snake_case when referring to built-in Godot signals. Prefer using the names exposed in the [code]SignalName[/code] class to avoid allocating a new [StringName] on each call. </description> </method> <method name="has_user_signal" qualifiers="const"> @@ -898,7 +898,7 @@ <param index="1" name="callable" type="Callable" /> <description> Returns [code]true[/code] if a connection exists between the given [param signal] name and [param callable]. - [b]Note:[/b] In C#, [param signal] must be in snake_case when referring to built-in Godot methods. Prefer using the names exposed in the [code]SignalName[/code] class to avoid allocating a new [StringName] on each call. + [b]Note:[/b] In C#, [param signal] must be in snake_case when referring to built-in Godot signals. Prefer using the names exposed in the [code]SignalName[/code] class to avoid allocating a new [StringName] on each call. </description> </method> <method name="is_queued_for_deletion" qualifiers="const"> diff --git a/doc/classes/PCKPacker.xml b/doc/classes/PCKPacker.xml index ec0300c068..f8f7dbee01 100644 --- a/doc/classes/PCKPacker.xml +++ b/doc/classes/PCKPacker.xml @@ -26,11 +26,18 @@ <methods> <method name="add_file"> <return type="int" enum="Error" /> - <param index="0" name="pck_path" type="String" /> + <param index="0" name="target_path" type="String" /> <param index="1" name="source_path" type="String" /> <param index="2" name="encrypt" type="bool" default="false" /> <description> - Adds the [param source_path] file to the current PCK package at the [param pck_path] internal path (should start with [code]res://[/code]). + Adds the [param source_path] file to the current PCK package at the [param target_path] internal path. The [code]res://[/code] prefix for [param target_path] is optional and stripped internally. + </description> + </method> + <method name="add_file_removal"> + <return type="int" enum="Error" /> + <param index="0" name="target_path" type="String" /> + <description> + Registers a file removal of the [param target_path] internal path to the PCK. This is mainly used for patches. If the file at this path has been loaded from a previous PCK, it will be removed. The [code]res://[/code] prefix for [param target_path] is optional and stripped internally. </description> </method> <method name="flush"> diff --git a/doc/classes/PackedScene.xml b/doc/classes/PackedScene.xml index 415e468e21..baff5fed57 100644 --- a/doc/classes/PackedScene.xml +++ b/doc/classes/PackedScene.xml @@ -7,7 +7,7 @@ A simplified interface to a scene file. Provides access to operations and checks that can be performed on the scene resource itself. Can be used to save a node to a file. When saving, the node as well as all the nodes it owns get saved (see [member Node.owner] property). [b]Note:[/b] The node doesn't need to own itself. - [b]Example of loading a saved scene:[/b] + [b]Example:[/b] Load a saved scene: [codeblocks] [gdscript] # Use load() instead of preload() if the path isn't known at compile-time. @@ -22,7 +22,7 @@ AddChild(scene); [/csharp] [/codeblocks] - [b]Example of saving a node with different owners:[/b] The following example creates 3 objects: [Node2D] ([code]node[/code]), [RigidBody2D] ([code]body[/code]) and [CollisionObject2D] ([code]collision[/code]). [code]collision[/code] is a child of [code]body[/code] which is a child of [code]node[/code]. Only [code]body[/code] is owned by [code]node[/code] and [method pack] will therefore only save those two nodes, but not [code]collision[/code]. + [b]Example:[/b] Save a node with different owners. The following example creates 3 objects: [Node2D] ([code]node[/code]), [RigidBody2D] ([code]body[/code]) and [CollisionObject2D] ([code]collision[/code]). [code]collision[/code] is a child of [code]body[/code] which is a child of [code]node[/code]. Only [code]body[/code] is owned by [code]node[/code] and [method pack] will therefore only save those two nodes, but not [code]collision[/code]. [codeblocks] [gdscript] # Create the objects. diff --git a/doc/classes/PacketPeerUDP.xml b/doc/classes/PacketPeerUDP.xml index 12d3178797..05b6e646c0 100644 --- a/doc/classes/PacketPeerUDP.xml +++ b/doc/classes/PacketPeerUDP.xml @@ -4,7 +4,32 @@ UDP packet peer. </brief_description> <description> - UDP packet peer. Can be used to send raw UDP packets as well as [Variant]s. + UDP packet peer. Can be used to send and receive raw UDP packets as well as [Variant]s. + [b]Example:[/b] Send a packet: + [codeblock] + var peer = PacketPeerUDP.new() + + # Optionally, you can select the local port used to send the packet. + peer.bind(4444) + + peer.set_dest_address("1.1.1.1", 4433) + peer.put_packet("hello".to_utf8_buffer()) + [/codeblock] + [b]Example:[/b] Listen for packets: + [codeblock] + var peer + + func _ready(): + peer = PacketPeerUDP.new() + peer.bind(4433) + + + func _process(_delta): + if peer.get_available_packet_count() > 0: + var array_bytes = peer.get_packet() + var packet_string = array_bytes.get_string_from_ascii() + print("Received message: ", packet_string) + [/codeblock] [b]Note:[/b] When exporting to Android, make sure to enable the [code]INTERNET[/code] permission in the Android export preset before exporting the project or using one-click deploy. Otherwise, network communication of any kind will be blocked by Android. </description> <tutorials> diff --git a/doc/classes/PhysicalBone3D.xml b/doc/classes/PhysicalBone3D.xml index ca1948e8e1..e2ad3db0a5 100644 --- a/doc/classes/PhysicalBone3D.xml +++ b/doc/classes/PhysicalBone3D.xml @@ -21,6 +21,9 @@ <return type="void" /> <param index="0" name="impulse" type="Vector3" /> <description> + Applies a directional impulse without affecting rotation. + An impulse is time-independent! Applying an impulse every frame would result in a framerate-dependent force. For this reason, it should only be used when simulating one-time impacts (use the "_integrate_forces" functions otherwise). + This is equivalent to using [method apply_impulse] at the body's center of mass. </description> </method> <method name="apply_impulse"> @@ -28,27 +31,33 @@ <param index="0" name="impulse" type="Vector3" /> <param index="1" name="position" type="Vector3" default="Vector3(0, 0, 0)" /> <description> + Applies a positioned impulse to the PhysicsBone3D. + An impulse is time-independent! Applying an impulse every frame would result in a framerate-dependent force. For this reason, it should only be used when simulating one-time impacts (use the "_integrate_forces" functions otherwise). + [param position] is the offset from the PhysicsBone3D origin in global coordinates. </description> </method> <method name="get_bone_id" qualifiers="const"> <return type="int" /> <description> + Returns the unique identifier of the PhysicsBone3D. </description> </method> <method name="get_simulate_physics"> <return type="bool" /> <description> + Returns [code]true[/code] if the PhysicsBone3D is allowed to simulate physics. </description> </method> <method name="is_simulating_physics"> <return type="bool" /> <description> + Returns [code]true[/code] if the PhysicsBone3D is currently simulating physics. </description> </method> </methods> <members> <member name="angular_damp" type="float" setter="set_angular_damp" getter="get_angular_damp" default="0.0"> - Damps the body's rotation. By default, the body will use the [b]Default Angular Damp[/b] in [b]Project > Project Settings > Physics > 3d[/b] or any value override set by an [Area3D] the body is in. Depending on [member angular_damp_mode], you can set [member angular_damp] to be added to or to replace the body's damping value. + Damps the body's rotation. By default, the body will use the [member ProjectSettings.physics/3d/default_angular_damp] project setting or any value override set by an [Area3D] the body is in. Depending on [member angular_damp_mode], you can set [member angular_damp] to be added to or to replace the body's damping value. See [member ProjectSettings.physics/3d/default_angular_damp] for more details about damping. </member> <member name="angular_damp_mode" type="int" setter="set_angular_damp_mode" getter="get_angular_damp_mode" enum="PhysicalBone3D.DampMode" default="0"> @@ -75,7 +84,7 @@ The body's friction, from [code]0[/code] (frictionless) to [code]1[/code] (max friction). </member> <member name="gravity_scale" type="float" setter="set_gravity_scale" getter="get_gravity_scale" default="1.0"> - This is multiplied by the global 3D gravity setting found in [b]Project > Project Settings > Physics > 3d[/b] to produce the body's gravity. For example, a value of 1 will be normal gravity, 2 will apply double gravity, and 0.5 will apply half gravity to this object. + This is multiplied by [member ProjectSettings.physics/3d/default_gravity] to produce this body's gravity. For example, a value of [code]1.0[/code] will apply normal gravity, [code]2.0[/code] will apply double the gravity, and [code]0.5[/code] will apply half the gravity to this body. </member> <member name="joint_offset" type="Transform3D" setter="set_joint_offset" getter="get_joint_offset" default="Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)"> Sets the joint's transform. @@ -87,7 +96,7 @@ Sets the joint type. See [enum JointType] for possible values. </member> <member name="linear_damp" type="float" setter="set_linear_damp" getter="get_linear_damp" default="0.0"> - Damps the body's movement. By default, the body will use the [b]Default Linear Damp[/b] in [b]Project > Project Settings > Physics > 3d[/b] or any value override set by an [Area3D] the body is in. Depending on [member linear_damp_mode], you can set [member linear_damp] to be added to or to replace the body's damping value. + Damps the body's movement. By default, the body will use [member ProjectSettings.physics/3d/default_linear_damp] or any value override set by an [Area3D] the body is in. Depending on [member linear_damp_mode], [member linear_damp] may be added to or replace the body's damping value. See [member ProjectSettings.physics/3d/default_linear_damp] for more details about damping. </member> <member name="linear_damp_mode" type="int" setter="set_linear_damp_mode" getter="get_linear_damp_mode" enum="PhysicalBone3D.DampMode" default="0"> @@ -108,16 +117,22 @@ In this mode, the body's damping value replaces any value set in areas or the default value. </constant> <constant name="JOINT_TYPE_NONE" value="0" enum="JointType"> + No joint is applied to the PhysicsBone3D. </constant> <constant name="JOINT_TYPE_PIN" value="1" enum="JointType"> + A pin joint is applied to the PhysicsBone3D. </constant> <constant name="JOINT_TYPE_CONE" value="2" enum="JointType"> + A cone joint is applied to the PhysicsBone3D. </constant> <constant name="JOINT_TYPE_HINGE" value="3" enum="JointType"> + A hinge joint is applied to the PhysicsBone3D. </constant> <constant name="JOINT_TYPE_SLIDER" value="4" enum="JointType"> + A slider joint is applied to the PhysicsBone3D. </constant> <constant name="JOINT_TYPE_6DOF" value="5" enum="JointType"> + A 6 degrees of freedom joint is applied to the PhysicsBone3D. </constant> </constants> </class> diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml index d73cda7460..9fd47cf7f5 100644 --- a/doc/classes/PopupMenu.xml +++ b/doc/classes/PopupMenu.xml @@ -135,8 +135,6 @@ Adds a new multistate item with text [param label]. Contrarily to normal binary items, multistate items can have more than two states, as defined by [param max_states]. The default value is defined by [param default_state]. An [param id] can optionally be provided, as well as an accelerator ([param accel]). If no [param id] is provided, one will be created from the index. If no [param accel] is provided, then the default value of 0 (corresponding to [constant @GlobalScope.KEY_NONE]) will be assigned to the item (which means it won't have any accelerator). See [method get_item_accelerator] for more info on accelerators. - [b]Note:[/b] Multistate items don't update their state automatically and must be done manually. See [method toggle_item_multistate], [method set_item_multistate] and [method get_item_multistate] for more info on how to control it. - Example usage: [codeblock] func _ready(): add_multistate_item("Item", 3, 0) @@ -152,6 +150,7 @@ print("Third state") ) [/codeblock] + [b]Note:[/b] Multistate items don't update their state automatically and must be done manually. See [method toggle_item_multistate], [method set_item_multistate] and [method get_item_multistate] for more info on how to control it. </description> </method> <method name="add_radio_check_item"> diff --git a/doc/classes/PrimitiveMesh.xml b/doc/classes/PrimitiveMesh.xml index 58a8da12da..ba48d2dcf5 100644 --- a/doc/classes/PrimitiveMesh.xml +++ b/doc/classes/PrimitiveMesh.xml @@ -18,7 +18,8 @@ <method name="get_mesh_arrays" qualifiers="const"> <return type="Array" /> <description> - Returns mesh arrays used to constitute surface of [Mesh]. The result can be passed to [method ArrayMesh.add_surface_from_arrays] to create a new surface. For example: + Returns the mesh arrays used to make up the surface of this primitive mesh. + [b]Example:[/b] Pass the result to [method ArrayMesh.add_surface_from_arrays] to create a new surface: [codeblocks] [gdscript] var c = CylinderMesh.new() diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index fff6c8d3bb..91961fcf02 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -103,7 +103,7 @@ <param index="0" name="name" type="StringName" /> <description> Similar to [method get_setting], but applies feature tag overrides if any exists and is valid. - [b]Example:[/b] If the setting override [code]"application/config/name.windows"[/code] exists, and the following code is executed on a [i]Windows[/i] operating system, the overridden setting is printed instead: + [b]Example:[/b] If the setting override [code]"application/config/name.windows"[/code] exists, and the following code is executed on a [i]Windows[/i] operating system, the overridden setting is printed instead: [codeblocks] [gdscript] print(ProjectSettings.get_setting_with_override("application/config/name")) @@ -2474,10 +2474,10 @@ Number of blur passes to use when computing screen-space ambient occlusion. A higher number will result in a smoother look, but will be slower to compute and will have less high-frequency detail. </member> <member name="rendering/environment/ssao/fadeout_from" type="float" setter="" getter="" default="50.0"> - Distance at which the screen-space ambient occlusion effect starts to fade out. Use this hide ambient occlusion at great distances. + Distance at which the screen-space ambient occlusion effect starts to fade out. Use this hide ambient occlusion from far away. </member> <member name="rendering/environment/ssao/fadeout_to" type="float" setter="" getter="" default="300.0"> - Distance at which the screen-space ambient occlusion is fully faded out. Use this hide ambient occlusion at great distances. + Distance at which the screen-space ambient occlusion is fully faded out. Use this hide ambient occlusion from far away. </member> <member name="rendering/environment/ssao/half_size" type="bool" setter="" getter="" default="true"> If [code]true[/code], screen-space ambient occlusion will be rendered at half size and then upscaled before being added to the scene. This is significantly faster but may miss small details. If [code]false[/code], screen-space ambient occlusion will be rendered at full size. @@ -2492,10 +2492,10 @@ Number of blur passes to use when computing screen-space indirect lighting. A higher number will result in a smoother look, but will be slower to compute and will have less high-frequency detail. </member> <member name="rendering/environment/ssil/fadeout_from" type="float" setter="" getter="" default="50.0"> - Distance at which the screen-space indirect lighting effect starts to fade out. Use this hide screen-space indirect lighting at great distances. + Distance at which the screen-space indirect lighting effect starts to fade out. Use this to hide screen-space indirect lighting from far away. </member> <member name="rendering/environment/ssil/fadeout_to" type="float" setter="" getter="" default="300.0"> - Distance at which the screen-space indirect lighting is fully faded out. Use this hide screen-space indirect lighting at great distances. + Distance at which the screen-space indirect lighting is fully faded out. Use this to hide screen-space indirect lighting from far away. </member> <member name="rendering/environment/ssil/half_size" type="bool" setter="" getter="" default="true"> If [code]true[/code], screen-space indirect lighting will be rendered at half size and then upscaled before being added to the scene. This is significantly faster but may miss small details and may result in some objects appearing to glow at their edges. @@ -2778,6 +2778,8 @@ [b]Forward Plus[/b]: High-end renderer designed for Desktop devices. Has a higher base overhead, but scales well with complex scenes. Not suitable for older devices or mobile. [b]Mobile[/b]: Modern renderer designed for mobile devices. Has a lower base overhead than Forward Plus, but does not scale as well to large scenes with many elements. [b]GL Compatibility[/b]: Low-end renderer designed for older devices. Based on the limitations of the OpenGL 3.3/ OpenGL ES 3.0 / WebGL 2 APIs. + This can be overridden using the [code]--rendering-method <method>[/code] command line argument. + [b]Note:[/b] The actual rendering method may be automatically changed by the engine as a result of a fallback, or a user-specified command line argument. To get the actual rendering method that is used at runtime, use [method RenderingServer.get_current_rendering_method] instead of reading this project setting's value. </member> <member name="rendering/renderer/rendering_method.mobile" type="String" setter="" getter="" default=""mobile""> Override for [member rendering/renderer/rendering_method] on mobile devices. @@ -2801,7 +2803,8 @@ Depending on the complexity of scenes, this value may be lowered or may need to be raised. </member> <member name="rendering/rendering_device/driver" type="String" setter="" getter=""> - Sets the driver to be used by the renderer when using a RenderingDevice-based renderer like the clustered renderer or the mobile renderer. This property can not be edited directly, instead, set the driver using the platform-specific overrides. + Sets the driver to be used by the renderer when using a RenderingDevice-based renderer like the clustered renderer or the mobile renderer. This property can't be edited directly. Instead, set the driver using the platform-specific overrides. This can be overridden using the [code]--rendering-driver <driver>[/code] command line argument. + [b]Note:[/b] The actual rendering driver may be automatically changed by the engine as a result of a fallback, or a user-specified command line argument. To get the actual rendering driver that is used at runtime, use [method RenderingServer.get_current_rendering_driver_name] instead of reading this project setting's value. </member> <member name="rendering/rendering_device/driver.android" type="String" setter="" getter=""> Android override for [member rendering/rendering_device/driver]. @@ -2890,11 +2893,11 @@ If [code]true[/code], forces vertex shading for all rendering. This can increase performance a lot, but also reduces quality immensely. Can be used to optimize performance on low-end mobile devices. </member> <member name="rendering/textures/canvas_textures/default_texture_filter" type="int" setter="" getter="" default="1"> - The default texture filtering mode to use on [CanvasItem]s. + The default texture filtering mode to use for [CanvasItem]s built-in texture. In shaders, this texture is accessed as [code]TEXTURE[/code]. [b]Note:[/b] For pixel art aesthetics, see also [member rendering/2d/snap/snap_2d_vertices_to_pixel] and [member rendering/2d/snap/snap_2d_transforms_to_pixel]. </member> <member name="rendering/textures/canvas_textures/default_texture_repeat" type="int" setter="" getter="" default="0"> - The default texture repeating mode to use on [CanvasItem]s. + The default texture repeating mode to use for [CanvasItem]s built-in texture. In shaders, this texture is accessed as [code]TEXTURE[/code]. </member> <member name="rendering/textures/decals/filter" type="int" setter="" getter="" default="3"> The filtering quality to use for [Decal] nodes. When using one of the anisotropic filtering modes, the anisotropic filtering level is controlled by [member rendering/textures/default_filters/anisotropic_filtering_level]. diff --git a/doc/classes/Projection.xml b/doc/classes/Projection.xml index 1665660da3..f781083abf 100644 --- a/doc/classes/Projection.xml +++ b/doc/classes/Projection.xml @@ -14,7 +14,8 @@ <constructor name="Projection"> <return type="Projection" /> <description> - Constructs a default-initialized [Projection] set to [constant IDENTITY]. + Constructs a default-initialized [Projection] identical to [constant IDENTITY]. + [b]Note:[/b] In C#, this constructs a [Projection] identical to [constant ZERO]. </description> </constructor> <constructor name="Projection"> diff --git a/doc/classes/Quaternion.xml b/doc/classes/Quaternion.xml index 665c6335f2..c74a6453e0 100644 --- a/doc/classes/Quaternion.xml +++ b/doc/classes/Quaternion.xml @@ -22,6 +22,7 @@ <return type="Quaternion" /> <description> Constructs a [Quaternion] identical to the [constant IDENTITY]. + [b]Note:[/b] In C#, this constructs a [Quaternion] with all of its components set to [code]0.0[/code]. </description> </constructor> <constructor name="Quaternion"> diff --git a/doc/classes/RDTextureFormat.xml b/doc/classes/RDTextureFormat.xml index f8de7feda0..ac875ab7c1 100644 --- a/doc/classes/RDTextureFormat.xml +++ b/doc/classes/RDTextureFormat.xml @@ -13,12 +13,14 @@ <return type="void" /> <param index="0" name="format" type="int" enum="RenderingDevice.DataFormat" /> <description> + Adds [param format] as a valid format for the corresponding [RDTextureView]'s [member RDTextureView.format_override] property. If any format is added as shareable, then the main [member format] must also be added. </description> </method> <method name="remove_shareable_format"> <return type="void" /> <param index="0" name="format" type="int" enum="RenderingDevice.DataFormat" /> <description> + Removes [param format] from the list of valid formats that the corresponding [RDTextureView]'s [member RDTextureView.format_override] property can be set to. </description> </method> </methods> diff --git a/doc/classes/RDTextureView.xml b/doc/classes/RDTextureView.xml index 30b6bfedf5..bd8102d553 100644 --- a/doc/classes/RDTextureView.xml +++ b/doc/classes/RDTextureView.xml @@ -10,7 +10,7 @@ </tutorials> <members> <member name="format_override" type="int" setter="set_format_override" getter="get_format_override" enum="RenderingDevice.DataFormat" default="218"> - Optional override for the data format to return sampled values in. The default value of [constant RenderingDevice.DATA_FORMAT_MAX] does not override the format. + Optional override for the data format to return sampled values in. The corresponding [RDTextureFormat] must have had this added as a shareable format. The default value of [constant RenderingDevice.DATA_FORMAT_MAX] does not override the format. </member> <member name="swizzle_a" type="int" setter="set_swizzle_a" getter="get_swizzle_a" enum="RenderingDevice.TextureSwizzle" default="6"> The channel to sample when sampling the alpha channel. diff --git a/doc/classes/Range.xml b/doc/classes/Range.xml index 820ff04b70..a76676489f 100644 --- a/doc/classes/Range.xml +++ b/doc/classes/Range.xml @@ -54,7 +54,7 @@ Minimum value. Range is clamped if [member value] is less than [member min_value]. </member> <member name="page" type="float" setter="set_page" getter="get_page" default="0.0"> - Page size. Used mainly for [ScrollBar]. ScrollBar's length is its size multiplied by [member page] over the difference between [member min_value] and [member max_value]. + Page size. Used mainly for [ScrollBar]. A [ScrollBar]'s grabber length is the [ScrollBar]'s size multiplied by [member page] over the difference between [member min_value] and [member max_value]. </member> <member name="ratio" type="float" setter="set_as_ratio" getter="get_as_ratio"> The value mapped between 0 and 1. diff --git a/doc/classes/RenderData.xml b/doc/classes/RenderData.xml index 065505e6c6..c2a598c43f 100644 --- a/doc/classes/RenderData.xml +++ b/doc/classes/RenderData.xml @@ -19,7 +19,7 @@ <method name="get_environment" qualifiers="const"> <return type="RID" /> <description> - Returns the [RID] of the environments object in the [RenderingServer] being used to render this viewport. + Returns the [RID] of the environment object in the [RenderingServer] being used to render this viewport. </description> </method> <method name="get_render_scene_buffers" qualifiers="const"> diff --git a/doc/classes/RenderSceneBuffersRD.xml b/doc/classes/RenderSceneBuffersRD.xml index 212a65337e..6a5aba1dbc 100644 --- a/doc/classes/RenderSceneBuffersRD.xml +++ b/doc/classes/RenderSceneBuffersRD.xml @@ -52,7 +52,7 @@ <param index="2" name="view_name" type="StringName" /> <param index="3" name="view" type="RDTextureView" /> <description> - Create a new texture view for an existing texture and cache this under the given view_name. Will return the existing teture view if it already exists. Will error if the source texture doesn't exist. + Create a new texture view for an existing texture and cache this under the given [param view_name]. Will return the existing texture view if it already exists. Will error if the source texture doesn't exist. </description> </method> <method name="get_color_layer"> @@ -61,7 +61,7 @@ <param index="1" name="msaa" type="bool" default="false" /> <description> Returns the specified layer from the color texture we are rendering 3D content to. - If [param msaa] is [b]true[/b] and MSAA is enabled, this returns the MSAA variant of the buffer. + If [param msaa] is [code]true[/code] and MSAA is enabled, this returns the MSAA variant of the buffer. </description> </method> <method name="get_color_texture"> @@ -69,7 +69,7 @@ <param index="0" name="msaa" type="bool" default="false" /> <description> Returns the color texture we are rendering 3D content to. If multiview is used this will be a texture array with all views. - If [param msaa] is [b]true[/b] and MSAA is enabled, this returns the MSAA variant of the buffer. + If [param msaa] is [code]true[/code] and MSAA is enabled, this returns the MSAA variant of the buffer. </description> </method> <method name="get_depth_layer"> @@ -78,7 +78,7 @@ <param index="1" name="msaa" type="bool" default="false" /> <description> Returns the specified layer from the depth texture we are rendering 3D content to. - If [param msaa] is [b]true[/b] and MSAA is enabled, this returns the MSAA variant of the buffer. + If [param msaa] is [code]true[/code] and MSAA is enabled, this returns the MSAA variant of the buffer. </description> </method> <method name="get_depth_texture"> @@ -86,7 +86,7 @@ <param index="0" name="msaa" type="bool" default="false" /> <description> Returns the depth texture we are rendering 3D content to. If multiview is used this will be a texture array with all views. - If [param msaa] is [b]true[/b] and MSAA is enabled, this returns the MSAA variant of the buffer. + If [param msaa] is [code]true[/code] and MSAA is enabled, this returns the MSAA variant of the buffer. </description> </method> <method name="get_fsr_sharpness" qualifiers="const"> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 284dc07fd4..26f80630bb 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -1548,6 +1548,20 @@ Tries to free an object in the RenderingServer. To avoid memory leaks, this should be called after using an object as memory management does not occur automatically when using RenderingServer directly. </description> </method> + <method name="get_current_rendering_driver_name" qualifiers="const"> + <return type="String" /> + <description> + Returns the name of the current rendering driver. This can be [code]vulkan[/code], [code]d3d12[/code], [code]metal[/code], [code]opengl3[/code], [code]opengl3_es[/code], or [code]opengl3_angle[/code]. See also [method get_current_rendering_method]. + The rendering driver is determined by [member ProjectSettings.rendering/rendering_device/driver], the [code]--rendering-driver[/code] command line argument that overrides this project setting, or an automatic fallback that is applied depending on the hardware. + </description> + </method> + <method name="get_current_rendering_method" qualifiers="const"> + <return type="String" /> + <description> + Returns the name of the current rendering method. This can be [code]forward_plus[/code], [code]mobile[/code], or [code]gl_compatibility[/code]. See also [method get_current_rendering_driver_name]. + The rendering method is determined by [member ProjectSettings.rendering/renderer/rendering_method], the [code]--rendering-method[/code] command line argument that overrides this project setting, or an automatic fallback that is applied depending on the hardware. + </description> + </method> <method name="get_default_clear_color"> <return type="Color" /> <description> @@ -1600,7 +1614,7 @@ <return type="RID" /> <description> Returns the RID of a 256×256 texture with a testing pattern on it (in [constant Image.FORMAT_RGB8] format). This texture will be created and returned on the first call to [method get_test_texture], then it will be cached for subsequent calls. See also [method get_white_texture]. - Example of getting the test texture and applying it to a [Sprite2D] node: + [b]Example:[/b] Get the test texture and apply it to a [Sprite2D] node: [codeblock] var texture_rid = RenderingServer.get_test_texture() var texture = ImageTexture.create_from_image(RenderingServer.texture_2d_get(texture_rid)) @@ -1641,7 +1655,7 @@ <return type="RID" /> <description> Returns the ID of a 4×4 white texture (in [constant Image.FORMAT_RGB8] format). This texture will be created and returned on the first call to [method get_white_texture], then it will be cached for subsequent calls. See also [method get_test_texture]. - Example of getting the white texture and applying it to a [Sprite2D] node: + [b]Example:[/b] Get the white texture and apply it to a [Sprite2D] node: [codeblock] var texture_rid = RenderingServer.get_white_texture() var texture = ImageTexture.create_from_image(RenderingServer.texture_2d_get(texture_rid)) @@ -3514,7 +3528,7 @@ <param index="0" name="texture" type="RID" /> <description> Returns an [Image] instance from the given [param texture] [RID]. - Example of getting the test texture from [method get_test_texture] and applying it to a [Sprite2D] node: + [b]Example:[/b] Get the test texture from [method get_test_texture] and apply it to a [Sprite2D] node: [codeblock] var texture_rid = RenderingServer.get_test_texture() var texture = ImageTexture.create_from_image(RenderingServer.texture_2d_get(texture_rid)) diff --git a/doc/classes/Resource.xml b/doc/classes/Resource.xml index 18d4047339..0f3a231cb7 100644 --- a/doc/classes/Resource.xml +++ b/doc/classes/Resource.xml @@ -37,7 +37,7 @@ <return type="void" /> <description> Override this method to customize the newly duplicated resource created from [method PackedScene.instantiate], if the original's [member resource_local_to_scene] is set to [code]true[/code]. - [b]Example:[/b] Set a random [code]damage[/code] value to every local resource from an instantiated scene. + [b]Example:[/b] Set a random [code]damage[/code] value to every local resource from an instantiated scene: [codeblock] extends Resource diff --git a/doc/classes/ResourceFormatLoader.xml b/doc/classes/ResourceFormatLoader.xml index 4e4adc86c4..cdbf8b3f9a 100644 --- a/doc/classes/ResourceFormatLoader.xml +++ b/doc/classes/ResourceFormatLoader.xml @@ -57,6 +57,7 @@ <return type="int" /> <param index="0" name="path" type="String" /> <description> + Should return the unique ID for the resource associated with the given path. If this method is not overridden, a [code].uid[/code] file is generated along with the resource file, containing the unique ID. </description> </method> <method name="_handles_type" qualifiers="virtual const"> diff --git a/doc/classes/ResourceImporterTexture.xml b/doc/classes/ResourceImporterTexture.xml index 0761702aa1..a39e48c7bf 100644 --- a/doc/classes/ResourceImporterTexture.xml +++ b/doc/classes/ResourceImporterTexture.xml @@ -90,9 +90,13 @@ <member name="process/size_limit" type="int" setter="" getter="" default="0"> If set to a value greater than [code]0[/code], the size of the texture is limited on import to a value smaller than or equal to the value specified here. For non-square textures, the size limit affects the longer dimension, with the shorter dimension scaled to preserve aspect ratio. Resizing is performed using cubic interpolation. This can be used to reduce memory usage without affecting the source images, or avoid issues with textures not displaying on mobile/web platforms (as these usually can't display textures larger than 4096×4096). + [b]Note:[/b] Even if this is set to [code]0[/code], import size is limited to the following dimensions for technical reasons. Depending on [member compress/mode], textures will be downsampled on import if necessary: + - [b]Lossy:[/b] 16383 pixels width or height, whichever is larger; + - [b]Basis Universal:[/b] 16384 pixels width or height, whichever is larger; + - [b]All other modes:[/b] 32768 pixels width or height, whichever is larger. </member> <member name="roughness/mode" type="int" setter="" getter="" default="0"> - The color channel to consider as a roughness map in this texture. Only effective if Roughness > Src Normal is not empty. + The color channel to consider as a roughness map in this texture. Only effective if [member roughness/src_normal] is not empty. </member> <member name="roughness/src_normal" type="String" setter="" getter="" default=""""> The path to the texture to consider as a normal map for roughness filtering on import. Specifying this can help decrease specular aliasing slightly in 3D. diff --git a/doc/classes/ResourceLoader.xml b/doc/classes/ResourceLoader.xml index f718ad15d8..ae862dd52f 100644 --- a/doc/classes/ResourceLoader.xml +++ b/doc/classes/ResourceLoader.xml @@ -7,6 +7,7 @@ A singleton used to load resource files from the filesystem. It uses the many [ResourceFormatLoader] classes registered in the engine (either built-in or from a plugin) to load files into memory and convert them to a format that can be used by the engine. [b]Note:[/b] You have to import the files into the engine first to load them using [method load]. If you want to load [Image]s at run-time, you may use [method Image.load]. If you want to import audio files, you can use the snippet described in [member AudioStreamMP3.data]. + [b]Note:[/b] Non-resource files such as plain text files cannot be read using [ResourceLoader]. Use [FileAccess] for those files instead, and be aware that non-resource files are not exported by default (see notes in the [FileAccess] class description for instructions on exporting them). </description> <tutorials> <link title="Operating System Testing Demo">https://godotengine.org/asset-library/asset/2789</link> @@ -74,6 +75,13 @@ Once a resource has been loaded by the engine, it is cached in memory for faster access, and future calls to the [method load] method will use the cached version. The cached resource can be overridden by using [method Resource.take_over_path] on a new resource for that same path. </description> </method> + <method name="list_directory"> + <return type="PackedStringArray" /> + <param index="0" name="directory_path" type="String" /> + <description> + Lists a directory (as example: "res://assets/enemies"), returning all resources contained within. The resource files are the original file names as visible in the editor before exporting. + </description> + </method> <method name="load"> <return type="Resource" /> <param index="0" name="path" type="String" /> @@ -104,7 +112,7 @@ <param index="1" name="progress" type="Array" default="[]" /> <description> Returns the status of a threaded loading operation started with [method load_threaded_request] for the resource at [param path]. See [enum ThreadLoadStatus] for possible return values. - An array variable can optionally be passed via [param progress], and will return a one-element array containing the ratio of completion of the threaded loading (between [code]0.0[/code] and [code]1.0[/code]). + An array variable can optionally be passed via [param progress], and will return a one-element array containing the ratio of completion of the threaded loading (between [code]0.0[/code] and [code]1.0[/code]). [b]Note:[/b] The recommended way of using this method is to call it during different frames (e.g., in [method Node._process], instead of a loop). </description> </method> diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index 2ac346b5c2..8472e57840 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -225,8 +225,8 @@ <return type="void" /> <param index="0" name="effect" type="Variant" /> <description> - Installs a custom effect. This can also be done in the RichTextLabel inspector using the [member custom_effects] property. [param effect] should be a valid [RichTextEffect]. - Example RichTextEffect: + Installs a custom effect. This can also be done in the Inspector through the [member custom_effects] property. [param effect] should be a valid [RichTextEffect]. + [b]Example:[/b] With the following script extending from [RichTextEffect]: [codeblock] # effect.gd class_name MyCustomEffect @@ -236,7 +236,7 @@ # ... [/codeblock] - Registering the above effect in RichTextLabel from script: + The above effect can be installed in [RichTextLabel] from a script: [codeblock] # rich_text_label.gd extends RichTextLabel diff --git a/doc/classes/RigidBody2D.xml b/doc/classes/RigidBody2D.xml index 5661d1a276..1977b238e4 100644 --- a/doc/classes/RigidBody2D.xml +++ b/doc/classes/RigidBody2D.xml @@ -123,7 +123,7 @@ </methods> <members> <member name="angular_damp" type="float" setter="set_angular_damp" getter="get_angular_damp" default="0.0"> - Damps the body's rotation. By default, the body will use the [b]Default Angular Damp[/b] in [b]Project > Project Settings > Physics > 2d[/b] or any value override set by an [Area2D] the body is in. Depending on [member angular_damp_mode], you can set [member angular_damp] to be added to or to replace the body's damping value. + Damps the body's rotation. By default, the body will use the [member ProjectSettings.physics/2d/default_angular_damp] setting or any value override set by an [Area2D] the body is in. Depending on [member angular_damp_mode], you can set [member angular_damp] to be added to or to replace the body's damping value. See [member ProjectSettings.physics/2d/default_angular_damp] for more details about damping. </member> <member name="angular_damp_mode" type="int" setter="set_angular_damp_mode" getter="get_angular_damp_mode" enum="RigidBody2D.DampMode" default="0"> @@ -172,7 +172,7 @@ For a body that is always frozen, use [StaticBody2D] or [AnimatableBody2D] instead. </member> <member name="gravity_scale" type="float" setter="set_gravity_scale" getter="get_gravity_scale" default="1.0"> - Multiplies the gravity applied to the body. The body's gravity is calculated from the [b]Default Gravity[/b] value in [b]Project > Project Settings > Physics > 2d[/b] and/or any additional gravity vector applied by [Area2D]s. + Multiplies the gravity applied to the body. The body's gravity is calculated from the [member ProjectSettings.physics/2d/default_gravity] project setting and/or any additional gravity vector applied by [Area2D]s. </member> <member name="inertia" type="float" setter="set_inertia" getter="get_inertia" default="0.0"> The body's moment of inertia. This is like mass, but for rotation: it determines how much torque it takes to rotate the body. The moment of inertia is usually computed automatically from the mass and the shapes, but this property allows you to set a custom value. @@ -201,7 +201,7 @@ [/codeblocks] </member> <member name="linear_damp" type="float" setter="set_linear_damp" getter="get_linear_damp" default="0.0"> - Damps the body's movement. By default, the body will use the [b]Default Linear Damp[/b] in [b]Project > Project Settings > Physics > 2d[/b] or any value override set by an [Area2D] the body is in. Depending on [member linear_damp_mode], you can set [member linear_damp] to be added to or to replace the body's damping value. + Damps the body's movement. By default, the body will use the [member ProjectSettings.physics/2d/default_linear_damp] setting or any value override set by an [Area2D] the body is in. Depending on [member linear_damp_mode], you can set [member linear_damp] to be added to or to replace the body's damping value. See [member ProjectSettings.physics/2d/default_linear_damp] for more details about damping. </member> <member name="linear_damp_mode" type="int" setter="set_linear_damp_mode" getter="get_linear_damp_mode" enum="RigidBody2D.DampMode" default="0"> diff --git a/doc/classes/RigidBody3D.xml b/doc/classes/RigidBody3D.xml index dae904e2a3..de6d5cde3d 100644 --- a/doc/classes/RigidBody3D.xml +++ b/doc/classes/RigidBody3D.xml @@ -130,7 +130,7 @@ </methods> <members> <member name="angular_damp" type="float" setter="set_angular_damp" getter="get_angular_damp" default="0.0"> - Damps the body's rotation. By default, the body will use the [b]Default Angular Damp[/b] in [b]Project > Project Settings > Physics > 3d[/b] or any value override set by an [Area3D] the body is in. Depending on [member angular_damp_mode], you can set [member angular_damp] to be added to or to replace the body's damping value. + Damps the body's rotation. By default, the body will use the [member ProjectSettings.physics/3d/default_angular_damp] project setting or any value override set by an [Area3D] the body is in. Depending on [member angular_damp_mode], you can set [member angular_damp] to be added to or to replace the body's damping value. See [member ProjectSettings.physics/3d/default_angular_damp] for more details about damping. </member> <member name="angular_damp_mode" type="int" setter="set_angular_damp_mode" getter="get_angular_damp_mode" enum="RigidBody3D.DampMode" default="0"> @@ -179,7 +179,7 @@ For a body that is always frozen, use [StaticBody3D] or [AnimatableBody3D] instead. </member> <member name="gravity_scale" type="float" setter="set_gravity_scale" getter="get_gravity_scale" default="1.0"> - This is multiplied by the global 3D gravity setting found in [b]Project > Project Settings > Physics > 3d[/b] to produce RigidBody3D's gravity. For example, a value of 1 will be normal gravity, 2 will apply double gravity, and 0.5 will apply half gravity to this object. + This is multiplied by [member ProjectSettings.physics/3d/default_gravity] to produce this body's gravity. For example, a value of [code]1.0[/code] will apply normal gravity, [code]2.0[/code] will apply double the gravity, and [code]0.5[/code] will apply half the gravity to this body. </member> <member name="inertia" type="Vector3" setter="set_inertia" getter="get_inertia" default="Vector3(0, 0, 0)"> The body's moment of inertia. This is like mass, but for rotation: it determines how much torque it takes to rotate the body on each axis. The moment of inertia is usually computed automatically from the mass and the shapes, but this property allows you to set a custom value. @@ -208,7 +208,7 @@ [/codeblocks] </member> <member name="linear_damp" type="float" setter="set_linear_damp" getter="get_linear_damp" default="0.0"> - Damps the body's movement. By default, the body will use the [b]Default Linear Damp[/b] in [b]Project > Project Settings > Physics > 3d[/b] or any value override set by an [Area3D] the body is in. Depending on [member linear_damp_mode], you can set [member linear_damp] to be added to or to replace the body's damping value. + Damps the body's movement. By default, the body will use the [member ProjectSettings.physics/3d/default_linear_damp] project setting or any value override set by an [Area3D] the body is in. Depending on [member linear_damp_mode], you can set [member linear_damp] to be added to or to replace the body's damping value. See [member ProjectSettings.physics/3d/default_linear_damp] for more details about damping. </member> <member name="linear_damp_mode" type="int" setter="set_linear_damp_mode" getter="get_linear_damp_mode" enum="RigidBody3D.DampMode" default="0"> diff --git a/doc/classes/SkeletonModification2DTwoBoneIK.xml b/doc/classes/SkeletonModification2DTwoBoneIK.xml index 1c7bb32f4a..d2417ba7bf 100644 --- a/doc/classes/SkeletonModification2DTwoBoneIK.xml +++ b/doc/classes/SkeletonModification2DTwoBoneIK.xml @@ -65,7 +65,7 @@ </methods> <members> <member name="flip_bend_direction" type="bool" setter="set_flip_bend_direction" getter="get_flip_bend_direction" default="false"> - If [code]true[/code], the bones in the modification will blend outward as opposed to inwards when contracting. If [code]false[/code], the bones will bend inwards when contracting. + If [code]true[/code], the bones in the modification will bend outward as opposed to inwards when contracting. If [code]false[/code], the bones will bend inwards when contracting. </member> <member name="target_maximum_distance" type="float" setter="set_target_maximum_distance" getter="get_target_maximum_distance" default="0.0"> The maximum distance the target can be at. If the target is farther than this distance, the modification will solve as if it's at this maximum distance. When set to [code]0[/code], the modification will solve without distance constraints. diff --git a/doc/classes/SplitContainer.xml b/doc/classes/SplitContainer.xml index 650c396190..daafbbdd87 100644 --- a/doc/classes/SplitContainer.xml +++ b/doc/classes/SplitContainer.xml @@ -30,7 +30,7 @@ </methods> <members> <member name="collapsed" type="bool" setter="set_collapsed" getter="is_collapsed" default="false"> - If [code]true[/code], the area of the first [Control] will be collapsed and the dragger will be disabled. + If [code]true[/code], the dragger will be disabled and the children will be sized as if the [member split_offset] was [code]0[/code]. </member> <member name="drag_area_highlight_in_editor" type="bool" setter="set_drag_area_highlight_in_editor" getter="is_drag_area_highlight_in_editor_enabled" default="false"> Highlights the drag area [Rect2] so you can see where it is during development. The drag area is gold if [member dragging_enabled] is [code]true[/code], and red if [code]false[/code]. diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 44795af473..e59734cf03 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -270,12 +270,12 @@ print("Visible {visible}, position {position}".format(node)) [/codeblock] See also the [url=$DOCS_URL/tutorials/scripting/gdscript/gdscript_format_string.html]GDScript format string[/url] tutorial. - [b]Note:[/b] The replacement of placeholders is not done all at once, instead each placeholder is replaced in the order they are passed, this means that if one of the replacement strings contains a key it will also be replaced. This can be very powerful, but can also cause unexpected results if you are not careful. If you do not need to perform replacement in the replacement strings, make sure your replacements do not contain placeholders to ensure reliable results. + [b]Note:[/b] Each replacement is done sequentially for each element of [param values], [b]not[/b] all at once. This means that if any element is inserted and it contains another placeholder, it may be changed by the next replacement. While this can be very useful, it often causes unexpected results. If not necessary, make sure [param values]'s elements do not contain placeholders. [codeblock] - print("{0} {1}".format(["{1}", "x"])) # Prints "x x". - print("{0} {1}".format(["x", "{0}"])) # Prints "x {0}". - print("{foo} {bar}".format({"foo": "{bar}", "bar": "baz"})) # Prints "baz baz". - print("{foo} {bar}".format({"bar": "baz", "foo": "{bar}"})) # Prints "{bar} baz". + print("{0} {1}".format(["{1}", "x"])) # Prints "x x". + print("{0} {1}".format(["x", "{0}"])) # Prints "x {0}". + print("{a} {b}".format({"a": "{b}", "b": "c"})) # Prints "c c". + print("{a} {b}".format({"b": "c", "a": "{b}"})) # Prints "{b} c". [/codeblock] [b]Note:[/b] In C#, it's recommended to [url=https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated]interpolate strings with "$"[/url], instead. </description> @@ -887,7 +887,7 @@ <return type="float" /> <param index="0" name="text" type="String" /> <description> - Returns the similarity index ([url=https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient]Sorensen-Dice coefficient[/url]) of this string compared to another. A result of [code]1.0[/code] means totally similar, while [code]0.0[/code] means totally dissimilar. + Returns the similarity index ([url=https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient]Sørensen-Dice coefficient[/url]) of this string compared to another. A result of [code]1.0[/code] means totally similar, while [code]0.0[/code] means totally dissimilar. [codeblock] print("ABC123".similarity("ABC123")) # Prints 1.0 print("ABC123".similarity("XYZ456")) # Prints 0.0 diff --git a/doc/classes/StringName.xml b/doc/classes/StringName.xml index 3a2b492496..4982bc36a8 100644 --- a/doc/classes/StringName.xml +++ b/doc/classes/StringName.xml @@ -247,6 +247,13 @@ print("User {id} is {name}.".format([["id", 42], ["name", "Godot"]])) [/codeblock] See also the [url=$DOCS_URL/tutorials/scripting/gdscript/gdscript_format_string.html]GDScript format string[/url] tutorial. + [b]Note:[/b] Each replacement is done sequentially for each element of [param values], [b]not[/b] all at once. This means that if any element is inserted and it contains another placeholder, it may be changed by the next replacement. While this can be very useful, it often causes unexpected results. If not necessary, make sure [param values]'s elements do not contain placeholders. + [codeblock] + print("{0} {1}".format(["{1}", "x"])) # Prints "x x". + print("{0} {1}".format(["x", "{0}"])) # Prints "x {0}". + print("{a} {b}".format({"a": "{b}", "b": "c"})) # Prints "c c". + print("{a} {b}".format({"b": "c", "a": "{b}"})) # Prints "{b} c". + [/codeblock] [b]Note:[/b] In C#, it's recommended to [url=https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated]interpolate strings with "$"[/url], instead. </description> </method> @@ -299,7 +306,7 @@ <param index="0" name="delimiter" type="String" /> <param index="1" name="slice" type="int" /> <description> - Splits the string using a [param delimiter] and returns the substring at index [param slice]. Returns an empty string if the [param slice] does not exist. + Splits the string using a [param delimiter] and returns the substring at index [param slice]. Returns the original string if [param delimiter] does not occur in the string. Returns an empty string if the [param slice] does not exist. This is faster than [method split], if you only need one substring. [codeblock] print("i/am/example/hi".get_slice("/", 2)) # Prints "example" @@ -782,7 +789,7 @@ <return type="float" /> <param index="0" name="text" type="String" /> <description> - Returns the similarity index ([url=https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient]Sorensen-Dice coefficient[/url]) of this string compared to another. A result of [code]1.0[/code] means totally similar, while [code]0.0[/code] means totally dissimilar. + Returns the similarity index ([url=https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient]Sørensen-Dice coefficient[/url]) of this string compared to another. A result of [code]1.0[/code] means totally similar, while [code]0.0[/code] means totally dissimilar. [codeblock] print("ABC123".similarity("ABC123")) # Prints 1.0 print("ABC123".similarity("XYZ456")) # Prints 0.0 @@ -871,7 +878,7 @@ <method name="to_ascii_buffer" qualifiers="const"> <return type="PackedByteArray" /> <description> - Converts the string to an [url=https://en.wikipedia.org/wiki/ASCII]ASCII[/url]/Latin-1 encoded [PackedByteArray]. This method is slightly faster than [method to_utf8_buffer], but replaces all unsupported characters with spaces. + Converts the string to an [url=https://en.wikipedia.org/wiki/ASCII]ASCII[/url]/Latin-1 encoded [PackedByteArray]. This method is slightly faster than [method to_utf8_buffer], but replaces all unsupported characters with spaces. This is the inverse of [method PackedByteArray.get_string_from_ascii]. </description> </method> <method name="to_camel_case" qualifiers="const"> @@ -885,11 +892,11 @@ <description> Converts the string representing a decimal number into a [float]. This method stops on the first non-number character, except the first decimal point ([code].[/code]) and the exponent letter ([code]e[/code]). See also [method is_valid_float]. [codeblock] - var a = "12.35".to_float() # a is 12.35 - var b = "1.2.3".to_float() # b is 1.2 - var c = "12xy3".to_float() # c is 12.0 - var d = "1e3".to_float() # d is 1000.0 - var e = "Hello!".to_int() # e is 0.0 + var a = "12.35".to_float() # a is 12.35 + var b = "1.2.3".to_float() # b is 1.2 + var c = "12xy3".to_float() # c is 12.0 + var d = "1e3".to_float() # d is 1000.0 + var e = "Hello!".to_float() # e is 0.0 [/codeblock] </description> </method> @@ -945,25 +952,25 @@ <method name="to_utf8_buffer" qualifiers="const"> <return type="PackedByteArray" /> <description> - Converts the string to a [url=https://en.wikipedia.org/wiki/UTF-8]UTF-8[/url] encoded [PackedByteArray]. This method is slightly slower than [method to_ascii_buffer], but supports all UTF-8 characters. For most cases, prefer using this method. + Converts the string to a [url=https://en.wikipedia.org/wiki/UTF-8]UTF-8[/url] encoded [PackedByteArray]. This method is slightly slower than [method to_ascii_buffer], but supports all UTF-8 characters. For most cases, prefer using this method. This is the inverse of [method PackedByteArray.get_string_from_utf8]. </description> </method> <method name="to_utf16_buffer" qualifiers="const"> <return type="PackedByteArray" /> <description> - Converts the string to a [url=https://en.wikipedia.org/wiki/UTF-16]UTF-16[/url] encoded [PackedByteArray]. + Converts the string to a [url=https://en.wikipedia.org/wiki/UTF-16]UTF-16[/url] encoded [PackedByteArray]. This is the inverse of [method PackedByteArray.get_string_from_utf16]. </description> </method> <method name="to_utf32_buffer" qualifiers="const"> <return type="PackedByteArray" /> <description> - Converts the string to a [url=https://en.wikipedia.org/wiki/UTF-32]UTF-32[/url] encoded [PackedByteArray]. + Converts the string to a [url=https://en.wikipedia.org/wiki/UTF-32]UTF-32[/url] encoded [PackedByteArray]. This is the inverse of [method PackedByteArray.get_string_from_utf32]. </description> </method> <method name="to_wchar_buffer" qualifiers="const"> <return type="PackedByteArray" /> <description> - Converts the string to a [url=https://en.wikipedia.org/wiki/Wide_character]wide character[/url] ([code]wchar_t[/code], UTF-16 on Windows, UTF-32 on other platforms) encoded [PackedByteArray]. + Converts the string to a [url=https://en.wikipedia.org/wiki/Wide_character]wide character[/url] ([code]wchar_t[/code], UTF-16 on Windows, UTF-32 on other platforms) encoded [PackedByteArray]. This is the inverse of [method PackedByteArray.get_string_from_wchar]. </description> </method> <method name="trim_prefix" qualifiers="const"> @@ -990,7 +997,7 @@ <method name="uri_decode" qualifiers="const"> <return type="String" /> <description> - Decodes the string from its URL-encoded format. This method is meant to properly decode the parameters in a URL when receiving an HTTP request. + Decodes the string from its URL-encoded format. This method is meant to properly decode the parameters in a URL when receiving an HTTP request. See also [method uri_encode]. [codeblocks] [gdscript] var url = "$DOCS_URL/?highlight=Godot%20Engine%3%docs" @@ -1006,7 +1013,7 @@ <method name="uri_encode" qualifiers="const"> <return type="String" /> <description> - Encodes the string to URL-friendly format. This method is meant to properly encode the parameters in a URL when sending an HTTP request. + Encodes the string to URL-friendly format. This method is meant to properly encode the parameters in a URL when sending an HTTP request. See also [method uri_decode]. [codeblocks] [gdscript] var prefix = "$DOCS_URL/?highlight=" diff --git a/doc/classes/StyleBoxTexture.xml b/doc/classes/StyleBoxTexture.xml index 14bceb4d4c..07d4b13f36 100644 --- a/doc/classes/StyleBoxTexture.xml +++ b/doc/classes/StyleBoxTexture.xml @@ -80,9 +80,9 @@ Modulates the color of the texture when this style box is drawn. </member> <member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" default="Rect2(0, 0, 0, 0)"> - Species a sub-region of the texture to use. - This is equivalent to first wrapping the texture in an [AtlasTexture] with the same region. - If empty ([code]Rect2(0, 0, 0, 0)[/code]), the whole texture will be used. + The region to use from the [member texture]. + This is equivalent to first wrapping the [member texture] in an [AtlasTexture] with the same region. + If empty ([code]Rect2(0, 0, 0, 0)[/code]), the whole [member texture] is used. </member> <member name="texture" type="Texture2D" setter="set_texture" getter="get_texture"> The texture to use when drawing this style box. diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml index 9c1525d8f8..9265e6b345 100644 --- a/doc/classes/SurfaceTool.xml +++ b/doc/classes/SurfaceTool.xml @@ -140,7 +140,7 @@ <param index="0" name="flip" type="bool" default="false" /> <description> Generates normals from vertices so you do not have to do it manually. If [param flip] is [code]true[/code], the resulting normals will be inverted. [method generate_normals] should be called [i]after[/i] generating geometry and [i]before[/i] committing the mesh using [method commit] or [method commit_to_arrays]. For correct display of normal-mapped surfaces, you will also have to generate tangents using [method generate_tangents]. - [b]Note:[/b] [method generate_normals] only works if the primitive type to be set to [constant Mesh.PRIMITIVE_TRIANGLES]. + [b]Note:[/b] [method generate_normals] only works if the primitive type is set to [constant Mesh.PRIMITIVE_TRIANGLES]. [b]Note:[/b] [method generate_normals] takes smooth groups into account. To generate smooth normals, set the smooth group to a value greater than or equal to [code]0[/code] using [method set_smooth_group] or leave the smooth group at the default of [code]0[/code]. To generate flat normals, set the smooth group to [code]-1[/code] using [method set_smooth_group] prior to adding vertices. </description> </method> diff --git a/doc/classes/SyntaxHighlighter.xml b/doc/classes/SyntaxHighlighter.xml index 27cee26c50..22d20d24e5 100644 --- a/doc/classes/SyntaxHighlighter.xml +++ b/doc/classes/SyntaxHighlighter.xml @@ -41,11 +41,11 @@ <return type="Dictionary" /> <param index="0" name="line" type="int" /> <description> - Returns syntax highlighting data for a single line. If the line is not cached, calls [method _get_line_syntax_highlighting] to calculate the data. - The return [Dictionary] is column number to [Dictionary]. The column number notes the start of a region, the region will end if another region is found, or at the end of the line. The nested [Dictionary] contains the data for that region, currently only the key "color" is supported. - [b]Example return:[/b] + Returns the syntax highlighting data for the line at index [param line]. If the line is not cached, calls [method _get_line_syntax_highlighting] first to calculate the data. + Each entry is a column number containing a nested [Dictionary]. The column number denotes the start of a region, the region will end if another region is found, or at the end of the line. The nested [Dictionary] contains the data for that region. Currently only the key [code]"color"[/code] is supported. + [b]Example:[/b] Possible return value. This means columns [code]0[/code] to [code]4[/code] should be red, and columns [code]5[/code] to the end of the line should be green: [codeblock] - var color_map = { + { 0: { "color": Color(1, 0, 0) }, @@ -54,7 +54,6 @@ } } [/codeblock] - This will color columns 0-4 red, and columns 5-eol in green. </description> </method> <method name="get_text_edit" qualifiers="const"> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index 7a4bef5747..13721d9d62 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -124,7 +124,6 @@ <return type="void" /> <description> Starts an edit for multiple carets. The edit must be ended with [method end_multicaret_edit]. Multicaret edits can be used to edit text at multiple carets and delay merging the carets until the end, so the caret indexes aren't affected immediately. [method begin_multicaret_edit] and [method end_multicaret_edit] can be nested, and the merge will happen at the last [method end_multicaret_edit]. - Example usage: [codeblock] begin_complex_operation() begin_multicaret_edit() @@ -764,7 +763,8 @@ <return type="bool" /> <param index="0" name="caret_index" type="int" default="0" /> <description> - Returns [code]true[/code] if the caret is visible on the screen. + Returns [code]true[/code] if the caret is visible, [code]false[/code] otherwise. A caret will be considered hidden if it is outside the scrollable area when scrolling is enabled. + [b]Note:[/b] [method is_caret_visible] does not account for a caret being off-screen if it is still within the scrollable area. It will return [code]true[/code] even if the caret is off-screen as long as it meets [TextEdit]'s own conditions for being visible. This includes uses of [member scroll_fit_content_width] and [member scroll_fit_content_height] that cause the [TextEdit] to expand beyond the viewport's bounds. </description> </method> <method name="is_dragging_cursor" qualifiers="const"> diff --git a/doc/classes/TileMapLayer.xml b/doc/classes/TileMapLayer.xml index 6cbec9c2aa..43708ca142 100644 --- a/doc/classes/TileMapLayer.xml +++ b/doc/classes/TileMapLayer.xml @@ -22,6 +22,21 @@ [b]Note:[/b] If the properties of [param tile_data] object should change over time, use [method notify_runtime_tile_data_update] to notify the [TileMapLayer] it needs an update. </description> </method> + <method name="_update_cells" qualifiers="virtual"> + <return type="void" /> + <param index="0" name="coords" type="Vector2i[]" /> + <param index="1" name="forced_cleanup" type="bool" /> + <description> + Called when this [TileMapLayer]'s cells need an internal update. This update may be caused from individual cells being modified or by a change in the [member tile_set] (causing all cells to be queued for an update). The first call to this function is always for initializing all the [TileMapLayer]'s cells. [param coords] contains the coordinates of all modified cells, roughly in the order they were modified. [param forced_cleanup] is [code]true[/code] when the [TileMapLayer]'s internals should be fully cleaned up. This is the case when: + - The layer is disabled; + - The layer is not visible; + - [member tile_set] is set to [code]null[/code]; + - The node is removed from the tree; + - The node is freed. + Note that any internal update happening while one of these conditions is verified is considered to be a "cleanup". See also [method update_internals]. + [b]Warning:[/b] Implementing this method may degrade the [TileMapLayer]'s performance. + </description> + </method> <method name="_use_tile_data_runtime_update" qualifiers="virtual"> <return type="bool" /> <param index="0" name="coords" type="Vector2i" /> @@ -120,7 +135,7 @@ <return type="Vector2i[]" /> <param index="0" name="coords" type="Vector2i" /> <description> - Returns the list of all neighboring cells to the one at [param coords]. + Returns the list of all neighboring cells to the one at [param coords]. Any neighboring cell is one that is touching edges, so for a square cell 4 cells would be returned, for a hexagon 6 cells are returned. </description> </method> <method name="get_used_cells" qualifiers="const"> diff --git a/doc/classes/TouchScreenButton.xml b/doc/classes/TouchScreenButton.xml index 5052518583..faeaaba5b6 100644 --- a/doc/classes/TouchScreenButton.xml +++ b/doc/classes/TouchScreenButton.xml @@ -5,7 +5,7 @@ </brief_description> <description> TouchScreenButton allows you to create on-screen buttons for touch devices. It's intended for gameplay use, such as a unit you have to touch to move. Unlike [Button], TouchScreenButton supports multitouch out of the box. Several TouchScreenButtons can be pressed at the same time with touch input. - This node inherits from [Node2D]. Unlike with [Control] nodes, you cannot set anchors on it. If you want to create menus or user interfaces, you may want to use [Button] nodes instead. To make button nodes react to touch events, you can enable the Emulate Mouse option in the Project Settings. + This node inherits from [Node2D]. Unlike with [Control] nodes, you cannot set anchors on it. If you want to create menus or user interfaces, you may want to use [Button] nodes instead. To make button nodes react to touch events, you can enable [member ProjectSettings.input_devices/pointing/emulate_mouse_from_touch] in the Project Settings. You can configure TouchScreenButton to be visible only on touch devices, helping you develop your game both for desktop and mobile devices. </description> <tutorials> diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml index 756716433e..665e5e9d67 100644 --- a/doc/classes/Transform2D.xml +++ b/doc/classes/Transform2D.xml @@ -20,6 +20,7 @@ <return type="Transform2D" /> <description> Constructs a [Transform2D] identical to [constant IDENTITY]. + [b]Note:[/b] In C#, this constructs a [Transform2D] with all of its components set to [constant Vector2.ZERO]. </description> </constructor> <constructor name="Transform2D"> diff --git a/doc/classes/Transform3D.xml b/doc/classes/Transform3D.xml index 30c141659a..98e9d56adb 100644 --- a/doc/classes/Transform3D.xml +++ b/doc/classes/Transform3D.xml @@ -21,6 +21,7 @@ <return type="Transform3D" /> <description> Constructs a [Transform3D] identical to the [constant IDENTITY]. + [b]Note:[/b] In C#, this constructs a [Transform3D] with its [member origin] and the components of its [member basis] set to [constant Vector3.ZERO]. </description> </constructor> <constructor name="Transform3D"> @@ -128,7 +129,7 @@ <param index="1" name="angle" type="float" /> <description> Returns a copy of this transform rotated around the given [param axis] by the given [param angle] (in radians). - The [param axis] must be a normalized vector. + The [param axis] must be a normalized vector in the transform's local coordinate system. For example, to rotate around the local X-axis, use [constant Vector3.RIGHT]. This method is an optimized version of multiplying the given transform [code]X[/code] with a corresponding rotation transform [code]R[/code] from the right, i.e., [code]X * R[/code]. This can be seen as transforming with respect to the local frame. </description> diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml index 86a8130acc..147d9fa4bd 100644 --- a/doc/classes/Tween.xml +++ b/doc/classes/Tween.xml @@ -218,8 +218,14 @@ <return type="Tween" /> <param index="0" name="ease" type="int" enum="Tween.EaseType" /> <description> - Sets the default ease type for [PropertyTweener]s and [MethodTweener]s animated by this [Tween]. - If not specified, the default value is [constant EASE_IN_OUT]. + Sets the default ease type for [PropertyTweener]s and [MethodTweener]s appended after this method. + Before this method is called, the default ease type is [constant EASE_IN_OUT]. + [codeblock] + var tween = create_tween() + tween.tween_property(self, "position", Vector2(300, 0), 0.5) # Uses EASE_IN_OUT. + tween.set_ease(Tween.EASE_IN) + tween.tween_property(self, "rotation_degrees", 45.0, 0.5) # Uses EASE_IN. + [/codeblock] </description> </method> <method name="set_loops"> @@ -271,14 +277,36 @@ <return type="Tween" /> <param index="0" name="trans" type="int" enum="Tween.TransitionType" /> <description> - Sets the default transition type for [PropertyTweener]s and [MethodTweener]s animated by this [Tween]. - If not specified, the default value is [constant TRANS_LINEAR]. + Sets the default transition type for [PropertyTweener]s and [MethodTweener]s appended after this method. + Before this method is called, the default transition type is [constant TRANS_LINEAR]. + [codeblock] + var tween = create_tween() + tween.tween_property(self, "position", Vector2(300, 0), 0.5) # Uses TRANS_LINEAR. + tween.set_trans(Tween.TRANS_SINE) + tween.tween_property(self, "rotation_degrees", 45.0, 0.5) # Uses TRANS_SINE. + [/codeblock] </description> </method> <method name="stop"> <return type="void" /> <description> Stops the tweening and resets the [Tween] to its initial state. This will not remove any appended [Tweener]s. + [b]Note:[/b] This does [i]not[/i] reset targets of [PropertyTweener]s to their values when the [Tween] first started. + [codeblock] + var tween = create_tween() + + # Will move from 0 to 500 over 1 second. + position.x = 0.0 + tween.tween_property(self, "position:x", 500, 1.0) + + # Will be at (about) 250 when the timer finishes. + await get_tree().create_timer(0.5).timeout + + # Will now move from (about) 250 to 500 over 1 second, + # thus at half the speed as before. + tween.stop() + tween.play() + [/codeblock] [b]Note:[/b] If a Tween is stopped and not bound to any node, it will exist indefinitely until manually started or invalidated. If you lose a reference to such Tween, you can retrieve it using [method SceneTree.get_processed_tweens]. </description> </method> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index c4319fd360..78b6d527ea 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -316,7 +316,7 @@ See also [member ProjectSettings.rendering/anti_aliasing/quality/msaa_2d] and [method RenderingServer.viewport_set_msaa_2d]. </member> <member name="msaa_3d" type="int" setter="set_msaa_3d" getter="get_msaa_3d" enum="Viewport.MSAA" default="0"> - The multisample antialiasing mode for 3D rendering. A higher number results in smoother edges at the cost of significantly worse performance. A value of [constant Viewport.MSAA_2X] or [constant Viewport.MSAA_4X] is best unless targeting very high-end systems. See also bilinear scaling 3d [member scaling_3d_mode] for supersampling, which provides higher quality but is much more expensive. This has no effect on shader-induced aliasing or texture aliasing. + The multisample antialiasing mode for 3D rendering. A higher number results in smoother edges at the cost of significantly worse performance. A value of [constant Viewport.MSAA_2X] or [constant Viewport.MSAA_4X] is best unless targeting very high-end systems. See also bilinear scaling 3D [member scaling_3d_mode] for supersampling, which provides higher quality but is much more expensive. This has no effect on shader-induced aliasing or texture aliasing. See also [member ProjectSettings.rendering/anti_aliasing/quality/msaa_3d] and [method RenderingServer.viewport_set_msaa_3d]. </member> <member name="own_world_3d" type="bool" setter="set_use_own_world_3d" getter="is_using_own_world_3d" default="false"> @@ -357,7 +357,7 @@ [b]Note:[/b] If this is set to [code]0[/code], no positional shadows will be visible at all. This can improve performance significantly on low-end systems by reducing both the CPU and GPU load (as fewer draw calls are needed to draw the scene without shadows). </member> <member name="scaling_3d_mode" type="int" setter="set_scaling_3d_mode" getter="get_scaling_3d_mode" enum="Viewport.Scaling3DMode" default="0"> - Sets scaling 3d mode. Bilinear scaling renders at different resolution to either undersample or supersample the viewport. FidelityFX Super Resolution 1.0, abbreviated to FSR, is an upscaling technology that produces high quality images at fast framerates by using a spatially aware upscaling algorithm. FSR is slightly more expensive than bilinear, but it produces significantly higher image quality. FSR should be used where possible. + Sets scaling 3D mode. Bilinear scaling renders at different resolution to either undersample or supersample the viewport. FidelityFX Super Resolution 1.0, abbreviated to FSR, is an upscaling technology that produces high quality images at fast framerates by using a spatially aware upscaling algorithm. FSR is slightly more expensive than bilinear, but it produces significantly higher image quality. FSR should be used where possible. To control this property on the root viewport, set the [member ProjectSettings.rendering/scaling_3d/mode] project setting. </member> <member name="scaling_3d_scale" type="float" setter="set_scaling_3d_scale" getter="get_scaling_3d_scale" default="1.0"> diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index 02110f0162..424941b842 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -725,8 +725,6 @@ <param index="0" name="files" type="PackedStringArray" /> <description> Emitted when files are dragged from the OS file manager and dropped in the game window. The argument is a list of file paths. - Note that this method only works with native windows, i.e. the main window and [Window]-derived nodes when [member Viewport.gui_embed_subwindows] is disabled in the main viewport. - Example usage: [codeblock] func _ready(): get_viewport().files_dropped.connect(on_files_dropped) @@ -734,6 +732,7 @@ func on_files_dropped(files): print(files) [/codeblock] + [b]Note:[/b] This signal only works with native windows, i.e. the main window and [Window]-derived nodes when [member Viewport.gui_embed_subwindows] is disabled in the main viewport. </description> </signal> <signal name="focus_entered"> diff --git a/doc/classes/XRCamera3D.xml b/doc/classes/XRCamera3D.xml index a7904b3ada..e49e884f33 100644 --- a/doc/classes/XRCamera3D.xml +++ b/doc/classes/XRCamera3D.xml @@ -4,7 +4,7 @@ A camera node with a few overrules for AR/VR applied, such as location tracking. </brief_description> <description> - This is a helper spatial node for our camera; note that, if stereoscopic rendering is applicable (VR-HMD), most of the camera properties are ignored, as the HMD information overrides them. The only properties that can be trusted are the near and far planes. + This is a helper 3D node for our camera. Note that, if stereoscopic rendering is applicable (VR-HMD), most of the camera properties are ignored, as the HMD information overrides them. The only properties that can be trusted are the near and far planes. The position and orientation of this node is automatically updated by the XR Server to represent the location of the HMD if such tracking is available and can thus be used by game logic. Note that, in contrast to the XR Controller, the render thread has access to the most up-to-date tracking data of the HMD and the location of the XRCamera3D can lag a few milliseconds behind what is used for rendering as a result. </description> <tutorials> diff --git a/doc/classes/XRController3D.xml b/doc/classes/XRController3D.xml index 8a068661c9..508752e0ae 100644 --- a/doc/classes/XRController3D.xml +++ b/doc/classes/XRController3D.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="XRController3D" inherits="XRNode3D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - A spatial node representing a spatially-tracked controller. + A 3D node representing a spatially-tracked controller. </brief_description> <description> - This is a helper spatial node that is linked to the tracking of controllers. It also offers several handy passthroughs to the state of buttons and such on the controllers. + This is a helper 3D node that is linked to the tracking of controllers. It also offers several handy passthroughs to the state of buttons and such on the controllers. Controllers are linked by their ID. You can create controller nodes before the controllers are available. If your game always uses two controllers (one for each hand), you can predefine the controllers with ID 1 and 2; they will become active as soon as the controllers are identified. If you expect additional controllers to be used, you should react to the signals and add XRController3D nodes to your scene. The position of the controller node is automatically updated by the [XRServer]. This makes this node ideal to add child nodes to visualize the controller. As many XR runtimes now use a configurable action map all inputs are named. diff --git a/doc/classes/XRNode3D.xml b/doc/classes/XRNode3D.xml index 82f4fa4ab9..fce3708d9a 100644 --- a/doc/classes/XRNode3D.xml +++ b/doc/classes/XRNode3D.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="XRNode3D" inherits="Node3D" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - A spatial node that has its position automatically updated by the [XRServer]. + A 3D node that has its position automatically updated by the [XRServer]. </brief_description> <description> This node can be bound to a specific pose of a [XRPositionalTracker] and will automatically have its [member Node3D.transform] updated by the [XRServer]. Nodes of this type must be added as children of the [XROrigin3D] node. diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp index 0cc89dfaca..0b1b0651c8 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp @@ -2160,6 +2160,7 @@ RDD::FenceID RenderingDeviceDriverD3D12::fence_create() { Error RenderingDeviceDriverD3D12::fence_wait(FenceID p_fence) { FenceInfo *fence = (FenceInfo *)(p_fence.id); + fence->d3d_fence->SetEventOnCompletion(fence->fence_value, fence->event_handle); DWORD res = WaitForSingleObjectEx(fence->event_handle, INFINITE, FALSE); #ifdef PIX_ENABLED PIXNotifyWakeFromFenceSignal(fence->event_handle); @@ -2254,7 +2255,6 @@ Error RenderingDeviceDriverD3D12::command_queue_execute_and_present(CommandQueue FenceInfo *fence = (FenceInfo *)(p_cmd_fence.id); fence->fence_value++; command_queue->d3d_queue->Signal(fence->d3d_fence.Get(), fence->fence_value); - fence->d3d_fence->SetEventOnCompletion(fence->fence_value, fence->event_handle); } } diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_unix.cpp index 5caa33100e..3eaf1b2885 100644 --- a/drivers/unix/net_socket_posix.cpp +++ b/drivers/unix/net_socket_unix.cpp @@ -1,5 +1,5 @@ /**************************************************************************/ -/* net_socket_posix.cpp */ +/* net_socket_unix.cpp */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#include "net_socket_posix.h" - // Some proprietary Unix-derived platforms don't expose Unix sockets // so this allows skipping this file to reimplement this API differently. -#ifndef UNIX_SOCKET_UNAVAILABLE +#if defined(UNIX_ENABLED) && !defined(UNIX_SOCKET_UNAVAILABLE) -#if defined(UNIX_ENABLED) +#include "net_socket_unix.h" #include <errno.h> #include <fcntl.h> @@ -62,44 +60,11 @@ #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP #endif -// Some custom defines to minimize ifdefs -#define SOCK_EMPTY -1 -#define SOCK_BUF(x) x -#define SOCK_CBUF(x) x -#define SOCK_IOCTL ioctl -#define SOCK_FIONREAD_LEN_TYPE int -#define SOCK_CLOSE ::close -#define SOCK_CONNECT(p_sock, p_addr, p_addr_len) ::connect(p_sock, p_addr, p_addr_len) - -/* Windows */ -#elif defined(WINDOWS_ENABLED) -#include <winsock2.h> -#include <ws2tcpip.h> - -#include <mswsock.h> -// Some custom defines to minimize ifdefs -#define SOCK_EMPTY INVALID_SOCKET -#define SOCK_BUF(x) (char *)(x) -#define SOCK_CBUF(x) (const char *)(x) -#define SOCK_IOCTL ioctlsocket -#define SOCK_FIONREAD_LEN_TYPE unsigned long -#define SOCK_CLOSE closesocket -// connect is broken on windows under certain conditions, reasons unknown: -// See https://github.com/godotengine/webrtc-native/issues/6 -#define SOCK_CONNECT(p_sock, p_addr, p_addr_len) ::WSAConnect(p_sock, p_addr, p_addr_len, nullptr, nullptr, nullptr, nullptr) - -// Workaround missing flag in MinGW -#if defined(__MINGW32__) && !defined(SIO_UDP_NETRESET) -#define SIO_UDP_NETRESET _WSAIOW(IOC_VENDOR, 15) -#endif - -#endif // UNIX_ENABLED - -size_t NetSocketPosix::_set_addr_storage(struct sockaddr_storage *p_addr, const IPAddress &p_ip, uint16_t p_port, IP::Type p_ip_type) { +size_t NetSocketUnix::_set_addr_storage(struct sockaddr_storage *p_addr, const IPAddress &p_ip, uint16_t p_port, IP::Type p_ip_type) { memset(p_addr, 0, sizeof(struct sockaddr_storage)); - if (p_ip_type == IP::TYPE_IPV6 || p_ip_type == IP::TYPE_ANY) { // IPv6 socket + if (p_ip_type == IP::TYPE_IPV6 || p_ip_type == IP::TYPE_ANY) { // IPv6 socket. - // IPv6 only socket with IPv4 address + // IPv6 only socket with IPv4 address. ERR_FAIL_COND_V(!p_ip.is_wildcard() && p_ip_type == IP::TYPE_IPV6 && p_ip.is_ipv4(), 0); struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)p_addr; @@ -111,14 +76,14 @@ size_t NetSocketPosix::_set_addr_storage(struct sockaddr_storage *p_addr, const addr6->sin6_addr = in6addr_any; } return sizeof(sockaddr_in6); - } else { // IPv4 socket + } else { // IPv4 socket. - // IPv4 socket with IPv6 address + // IPv4 socket with IPv6 address. ERR_FAIL_COND_V(!p_ip.is_wildcard() && !p_ip.is_ipv4(), 0); struct sockaddr_in *addr4 = (struct sockaddr_in *)p_addr; addr4->sin_family = AF_INET; - addr4->sin_port = htons(p_port); // short, network byte order + addr4->sin_port = htons(p_port); // Short, network byte order. if (p_ip.is_valid()) { memcpy(&addr4->sin_addr.s_addr, p_ip.get_ipv4(), 4); @@ -130,7 +95,7 @@ size_t NetSocketPosix::_set_addr_storage(struct sockaddr_storage *p_addr, const } } -void NetSocketPosix::_set_ip_port(struct sockaddr_storage *p_addr, IPAddress *r_ip, uint16_t *r_port) { +void NetSocketUnix::_set_ip_port(struct sockaddr_storage *p_addr, IPAddress *r_ip, uint16_t *r_port) { if (p_addr->ss_family == AF_INET) { struct sockaddr_in *addr4 = (struct sockaddr_in *)p_addr; if (r_ip) { @@ -150,34 +115,21 @@ void NetSocketPosix::_set_ip_port(struct sockaddr_storage *p_addr, IPAddress *r_ } } -NetSocket *NetSocketPosix::_create_func() { - return memnew(NetSocketPosix); +NetSocket *NetSocketUnix::_create_func() { + return memnew(NetSocketUnix); } -void NetSocketPosix::make_default() { -#if defined(WINDOWS_ENABLED) - if (_create == nullptr) { - WSADATA data; - WSAStartup(MAKEWORD(2, 2), &data); - } -#endif +void NetSocketUnix::make_default() { _create = _create_func; } -void NetSocketPosix::cleanup() { -#if defined(WINDOWS_ENABLED) - if (_create != nullptr) { - WSACleanup(); - } - _create = nullptr; -#endif +void NetSocketUnix::cleanup() { } -NetSocketPosix::NetSocketPosix() : - _sock(SOCK_EMPTY) { +NetSocketUnix::NetSocketUnix() { } -NetSocketPosix::~NetSocketPosix() { +NetSocketUnix::~NetSocketUnix() { close(); } @@ -188,30 +140,7 @@ NetSocketPosix::~NetSocketPosix() { #pragma GCC diagnostic ignored "-Wlogical-op" #endif -NetSocketPosix::NetError NetSocketPosix::_get_socket_error() const { -#if defined(WINDOWS_ENABLED) - int err = WSAGetLastError(); - if (err == WSAEISCONN) { - return ERR_NET_IS_CONNECTED; - } - if (err == WSAEINPROGRESS || err == WSAEALREADY) { - return ERR_NET_IN_PROGRESS; - } - if (err == WSAEWOULDBLOCK) { - return ERR_NET_WOULD_BLOCK; - } - if (err == WSAEADDRINUSE || err == WSAEADDRNOTAVAIL) { - return ERR_NET_ADDRESS_INVALID_OR_UNAVAILABLE; - } - if (err == WSAEACCES) { - return ERR_NET_UNAUTHORIZED; - } - if (err == WSAEMSGSIZE || err == WSAENOBUFS) { - return ERR_NET_BUFFER_TOO_SMALL; - } - print_verbose("Socket error: " + itos(err)); - return ERR_NET_OTHER; -#else +NetSocketUnix::NetError NetSocketUnix::_get_socket_error() const { if (errno == EISCONN) { return ERR_NET_IS_CONNECTED; } @@ -230,16 +159,15 @@ NetSocketPosix::NetError NetSocketPosix::_get_socket_error() const { if (errno == ENOBUFS) { return ERR_NET_BUFFER_TOO_SMALL; } - print_verbose("Socket error: " + itos(errno)); + print_verbose("Socket error: " + itos(errno) + "."); return ERR_NET_OTHER; -#endif } #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop #endif -bool NetSocketPosix::_can_use_ip(const IPAddress &p_ip, const bool p_for_bind) const { +bool NetSocketUnix::_can_use_ip(const IPAddress &p_ip, const bool p_for_bind) const { if (p_for_bind && !(p_ip.is_valid() || p_ip.is_wildcard())) { return false; } else if (!p_for_bind && !p_ip.is_valid()) { @@ -250,11 +178,11 @@ bool NetSocketPosix::_can_use_ip(const IPAddress &p_ip, const bool p_for_bind) c return !(_ip_type != IP::TYPE_ANY && !p_ip.is_wildcard() && _ip_type != type); } -_FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IPAddress p_ip, String p_if_name, bool p_add) { +_FORCE_INLINE_ Error NetSocketUnix::_change_multicast_group(IPAddress p_ip, String p_if_name, bool p_add) { ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); ERR_FAIL_COND_V(!_can_use_ip(p_ip, false), ERR_INVALID_PARAMETER); - // Need to force level and af_family to IP(v4) when using dual stacking and provided multicast group is IPv4 + // Need to force level and af_family to IP(v4) when using dual stacking and provided multicast group is IPv4. IP::Type type = _ip_type == IP::TYPE_ANY && p_ip.is_ipv4() ? IP::TYPE_IPV4 : _ip_type; // This needs to be the proper level for the multicast group, no matter if the socket is dual stacking. int level = type == IP::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; @@ -277,7 +205,7 @@ _FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IPAddress p_ip, Str for (const IPAddress &F : c.ip_addresses) { if (!F.is_ipv4()) { - continue; // Wrong IP type + continue; // Wrong IP type. } if_ip = F; break; @@ -304,7 +232,7 @@ _FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IPAddress p_ip, Str return OK; } -void NetSocketPosix::_set_socket(SOCKET_TYPE p_sock, IP::Type p_ip_type, bool p_is_stream) { +void NetSocketUnix::_set_socket(int p_sock, IP::Type p_ip_type, bool p_is_stream) { _sock = p_sock; _ip_type = p_ip_type; _is_stream = p_is_stream; @@ -312,15 +240,13 @@ void NetSocketPosix::_set_socket(SOCKET_TYPE p_sock, IP::Type p_ip_type, bool p_ _set_close_exec_enabled(true); } -void NetSocketPosix::_set_close_exec_enabled(bool p_enabled) { -#ifndef WINDOWS_ENABLED +void NetSocketUnix::_set_close_exec_enabled(bool p_enabled) { // Enable close on exec to avoid sharing with subprocesses. Off by default on Windows. int opts = fcntl(_sock, F_GETFD); fcntl(_sock, F_SETFD, opts | FD_CLOEXEC); -#endif } -Error NetSocketPosix::open(Type p_sock_type, IP::Type &ip_type) { +Error NetSocketUnix::open(Type p_sock_type, IP::Type &ip_type) { ERR_FAIL_COND_V(is_open(), ERR_ALREADY_IN_USE); ERR_FAIL_COND_V(ip_type > IP::TYPE_ANY || ip_type < IP::TYPE_NONE, ERR_INVALID_PARAMETER); @@ -336,7 +262,7 @@ Error NetSocketPosix::open(Type p_sock_type, IP::Type &ip_type) { int type = p_sock_type == TYPE_TCP ? SOCK_STREAM : SOCK_DGRAM; _sock = socket(family, type, protocol); - if (_sock == SOCK_EMPTY && ip_type == IP::TYPE_ANY) { + if (_sock == -1 && ip_type == IP::TYPE_ANY) { // Careful here, changing the referenced parameter so the caller knows that we are using an IPv4 socket // in place of a dual stack one, and further calls to _set_sock_addr will work as expected. ip_type = IP::TYPE_IPV4; @@ -344,11 +270,11 @@ Error NetSocketPosix::open(Type p_sock_type, IP::Type &ip_type) { _sock = socket(family, type, protocol); } - ERR_FAIL_COND_V(_sock == SOCK_EMPTY, FAILED); + ERR_FAIL_COND_V(_sock == -1, FAILED); _ip_type = ip_type; if (family == AF_INET6) { - // Select IPv4 over IPv6 mapping + // Select IPv4 over IPv6 mapping. set_ipv6_only_enabled(ip_type != IP::TYPE_ANY); } @@ -363,41 +289,27 @@ Error NetSocketPosix::open(Type p_sock_type, IP::Type &ip_type) { // Disable descriptor sharing with subprocesses. _set_close_exec_enabled(true); -#if defined(WINDOWS_ENABLED) - if (!_is_stream) { - // Disable windows feature/bug reporting WSAECONNRESET/WSAENETRESET when - // recv/recvfrom and an ICMP reply was received from a previous send/sendto. - unsigned long disable = 0; - if (ioctlsocket(_sock, SIO_UDP_CONNRESET, &disable) == SOCKET_ERROR) { - print_verbose("Unable to turn off UDP WSAECONNRESET behavior on Windows"); - } - if (ioctlsocket(_sock, SIO_UDP_NETRESET, &disable) == SOCKET_ERROR) { - // This feature seems not to be supported on wine. - print_verbose("Unable to turn off UDP WSAENETRESET behavior on Windows"); - } - } -#endif #if defined(SO_NOSIGPIPE) - // Disable SIGPIPE (should only be relevant to stream sockets, but seems to affect UDP too on iOS) + // Disable SIGPIPE (should only be relevant to stream sockets, but seems to affect UDP too on iOS). int par = 1; - if (setsockopt(_sock, SOL_SOCKET, SO_NOSIGPIPE, SOCK_CBUF(&par), sizeof(int)) != 0) { - print_verbose("Unable to turn off SIGPIPE on socket"); + if (setsockopt(_sock, SOL_SOCKET, SO_NOSIGPIPE, &par, sizeof(int)) != 0) { + print_verbose("Unable to turn off SIGPIPE on socket."); } #endif return OK; } -void NetSocketPosix::close() { - if (_sock != SOCK_EMPTY) { - SOCK_CLOSE(_sock); +void NetSocketUnix::close() { + if (_sock != -1) { + ::close(_sock); } - _sock = SOCK_EMPTY; + _sock = -1; _ip_type = IP::TYPE_NONE; _is_stream = false; } -Error NetSocketPosix::bind(IPAddress p_addr, uint16_t p_port) { +Error NetSocketUnix::bind(IPAddress p_addr, uint16_t p_port) { ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); ERR_FAIL_COND_V(!_can_use_ip(p_addr, true), ERR_INVALID_PARAMETER); @@ -406,7 +318,7 @@ Error NetSocketPosix::bind(IPAddress p_addr, uint16_t p_port) { if (::bind(_sock, (struct sockaddr *)&addr, addr_size) != 0) { NetError err = _get_socket_error(); - print_verbose("Failed to bind socket. Error: " + itos(err)); + print_verbose("Failed to bind socket. Error: " + itos(err) + "."); close(); return ERR_UNAVAILABLE; } @@ -414,7 +326,7 @@ Error NetSocketPosix::bind(IPAddress p_addr, uint16_t p_port) { return OK; } -Error NetSocketPosix::listen(int p_max_pending) { +Error NetSocketUnix::listen(int p_max_pending) { ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); if (::listen(_sock, p_max_pending) != 0) { @@ -427,26 +339,26 @@ Error NetSocketPosix::listen(int p_max_pending) { return OK; } -Error NetSocketPosix::connect_to_host(IPAddress p_host, uint16_t p_port) { +Error NetSocketUnix::connect_to_host(IPAddress p_host, uint16_t p_port) { ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); ERR_FAIL_COND_V(!_can_use_ip(p_host, false), ERR_INVALID_PARAMETER); struct sockaddr_storage addr; size_t addr_size = _set_addr_storage(&addr, p_host, p_port, _ip_type); - if (SOCK_CONNECT(_sock, (struct sockaddr *)&addr, addr_size) != 0) { + if (::connect(_sock, (struct sockaddr *)&addr, addr_size) != 0) { NetError err = _get_socket_error(); switch (err) { - // We are already connected + // We are already connected. case ERR_NET_IS_CONNECTED: return OK; - // Still waiting to connect, try again in a while + // Still waiting to connect, try again in a while. case ERR_NET_WOULD_BLOCK: case ERR_NET_IN_PROGRESS: return ERR_BUSY; default: - print_verbose("Connection to remote host failed!"); + print_verbose("Connection to remote host failed."); close(); return FAILED; } @@ -455,66 +367,9 @@ Error NetSocketPosix::connect_to_host(IPAddress p_host, uint16_t p_port) { return OK; } -Error NetSocketPosix::poll(PollType p_type, int p_timeout) const { +Error NetSocketUnix::poll(PollType p_type, int p_timeout) const { ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); -#if defined(WINDOWS_ENABLED) - bool ready = false; - fd_set rd, wr, ex; - fd_set *rdp = nullptr; - fd_set *wrp = nullptr; - FD_ZERO(&rd); - FD_ZERO(&wr); - FD_ZERO(&ex); - FD_SET(_sock, &ex); - struct timeval timeout = { p_timeout / 1000, (p_timeout % 1000) * 1000 }; - // For blocking operation, pass nullptr timeout pointer to select. - struct timeval *tp = nullptr; - if (p_timeout >= 0) { - // If timeout is non-negative, we want to specify the timeout instead. - tp = &timeout; - } - - switch (p_type) { - case POLL_TYPE_IN: - FD_SET(_sock, &rd); - rdp = &rd; - break; - case POLL_TYPE_OUT: - FD_SET(_sock, &wr); - wrp = ≀ - break; - case POLL_TYPE_IN_OUT: - FD_SET(_sock, &rd); - FD_SET(_sock, &wr); - rdp = &rd; - wrp = ≀ - } - int ret = select(1, rdp, wrp, &ex, tp); - - if (ret == SOCKET_ERROR) { - return FAILED; - } - - if (ret == 0) { - return ERR_BUSY; - } - - if (FD_ISSET(_sock, &ex)) { - _get_socket_error(); - print_verbose("Exception when polling socket."); - return FAILED; - } - - if (rdp && FD_ISSET(_sock, rdp)) { - ready = true; - } - if (wrp && FD_ISSET(_sock, wrp)) { - ready = true; - } - - return ready ? OK : ERR_BUSY; -#else struct pollfd pfd; pfd.fd = _sock; pfd.events = POLLIN; @@ -544,13 +399,12 @@ Error NetSocketPosix::poll(PollType p_type, int p_timeout) const { } return OK; -#endif } -Error NetSocketPosix::recv(uint8_t *p_buffer, int p_len, int &r_read) { +Error NetSocketUnix::recv(uint8_t *p_buffer, int p_len, int &r_read) { ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); - r_read = ::recv(_sock, SOCK_BUF(p_buffer), p_len, 0); + r_read = ::recv(_sock, p_buffer, p_len, 0); if (r_read < 0) { NetError err = _get_socket_error(); @@ -568,14 +422,14 @@ Error NetSocketPosix::recv(uint8_t *p_buffer, int p_len, int &r_read) { return OK; } -Error NetSocketPosix::recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IPAddress &r_ip, uint16_t &r_port, bool p_peek) { +Error NetSocketUnix::recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IPAddress &r_ip, uint16_t &r_port, bool p_peek) { ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); struct sockaddr_storage from; socklen_t len = sizeof(struct sockaddr_storage); memset(&from, 0, len); - r_read = ::recvfrom(_sock, SOCK_BUF(p_buffer), p_len, p_peek ? MSG_PEEK : 0, (struct sockaddr *)&from, &len); + r_read = ::recvfrom(_sock, p_buffer, p_len, p_peek ? MSG_PEEK : 0, (struct sockaddr *)&from, &len); if (r_read < 0) { NetError err = _get_socket_error(); @@ -606,7 +460,7 @@ Error NetSocketPosix::recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IPAddr return OK; } -Error NetSocketPosix::send(const uint8_t *p_buffer, int p_len, int &r_sent) { +Error NetSocketUnix::send(const uint8_t *p_buffer, int p_len, int &r_sent) { ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); int flags = 0; @@ -615,7 +469,7 @@ Error NetSocketPosix::send(const uint8_t *p_buffer, int p_len, int &r_sent) { flags = MSG_NOSIGNAL; } #endif - r_sent = ::send(_sock, SOCK_CBUF(p_buffer), p_len, flags); + r_sent = ::send(_sock, p_buffer, p_len, flags); if (r_sent < 0) { NetError err = _get_socket_error(); @@ -632,12 +486,12 @@ Error NetSocketPosix::send(const uint8_t *p_buffer, int p_len, int &r_sent) { return OK; } -Error NetSocketPosix::sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IPAddress p_ip, uint16_t p_port) { +Error NetSocketUnix::sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IPAddress p_ip, uint16_t p_port) { ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); struct sockaddr_storage addr; size_t addr_size = _set_addr_storage(&addr, p_ip, p_port, _ip_type); - r_sent = ::sendto(_sock, SOCK_CBUF(p_buffer), p_len, 0, (struct sockaddr *)&addr, addr_size); + r_sent = ::sendto(_sock, p_buffer, p_len, 0, (struct sockaddr *)&addr, addr_size); if (r_sent < 0) { NetError err = _get_socket_error(); @@ -654,7 +508,7 @@ Error NetSocketPosix::sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP return OK; } -Error NetSocketPosix::set_broadcasting_enabled(bool p_enabled) { +Error NetSocketUnix::set_broadcasting_enabled(bool p_enabled) { ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); // IPv6 has no broadcast support. if (_ip_type == IP::TYPE_IPV6) { @@ -662,90 +516,68 @@ Error NetSocketPosix::set_broadcasting_enabled(bool p_enabled) { } int par = p_enabled ? 1 : 0; - if (setsockopt(_sock, SOL_SOCKET, SO_BROADCAST, SOCK_CBUF(&par), sizeof(int)) != 0) { - WARN_PRINT("Unable to change broadcast setting"); + if (setsockopt(_sock, SOL_SOCKET, SO_BROADCAST, &par, sizeof(int)) != 0) { + WARN_PRINT("Unable to change broadcast setting."); return FAILED; } return OK; } -void NetSocketPosix::set_blocking_enabled(bool p_enabled) { +void NetSocketUnix::set_blocking_enabled(bool p_enabled) { ERR_FAIL_COND(!is_open()); int ret = 0; -#if defined(WINDOWS_ENABLED) - unsigned long par = p_enabled ? 0 : 1; - ret = SOCK_IOCTL(_sock, FIONBIO, &par); -#else int opts = fcntl(_sock, F_GETFL); if (p_enabled) { ret = fcntl(_sock, F_SETFL, opts & ~O_NONBLOCK); } else { ret = fcntl(_sock, F_SETFL, opts | O_NONBLOCK); } -#endif if (ret != 0) { - WARN_PRINT("Unable to change non-block mode"); + WARN_PRINT("Unable to change non-block mode."); } } -void NetSocketPosix::set_ipv6_only_enabled(bool p_enabled) { +void NetSocketUnix::set_ipv6_only_enabled(bool p_enabled) { ERR_FAIL_COND(!is_open()); // This option is only available in IPv6 sockets. ERR_FAIL_COND(_ip_type == IP::TYPE_IPV4); int par = p_enabled ? 1 : 0; - if (setsockopt(_sock, IPPROTO_IPV6, IPV6_V6ONLY, SOCK_CBUF(&par), sizeof(int)) != 0) { - WARN_PRINT("Unable to change IPv4 address mapping over IPv6 option"); + if (setsockopt(_sock, IPPROTO_IPV6, IPV6_V6ONLY, &par, sizeof(int)) != 0) { + WARN_PRINT("Unable to change IPv4 address mapping over IPv6 option."); } } -void NetSocketPosix::set_tcp_no_delay_enabled(bool p_enabled) { +void NetSocketUnix::set_tcp_no_delay_enabled(bool p_enabled) { ERR_FAIL_COND(!is_open()); - ERR_FAIL_COND(!_is_stream); // Not TCP + ERR_FAIL_COND(!_is_stream); // Not TCP. int par = p_enabled ? 1 : 0; - if (setsockopt(_sock, IPPROTO_TCP, TCP_NODELAY, SOCK_CBUF(&par), sizeof(int)) < 0) { - ERR_PRINT("Unable to set TCP no delay option"); + if (setsockopt(_sock, IPPROTO_TCP, TCP_NODELAY, &par, sizeof(int)) < 0) { + WARN_PRINT("Unable to set TCP no delay option."); } } -void NetSocketPosix::set_reuse_address_enabled(bool p_enabled) { +void NetSocketUnix::set_reuse_address_enabled(bool p_enabled) { ERR_FAIL_COND(!is_open()); -// On Windows, enabling SO_REUSEADDR actually would also enable reuse port, very bad on TCP. Denying... -// Windows does not have this option, SO_REUSEADDR in this magical world means SO_REUSEPORT -#ifndef WINDOWS_ENABLED - int par = p_enabled ? 1 : 0; - if (setsockopt(_sock, SOL_SOCKET, SO_REUSEADDR, SOCK_CBUF(&par), sizeof(int)) < 0) { - WARN_PRINT("Unable to set socket REUSEADDR option!"); - } -#endif -} - -void NetSocketPosix::set_reuse_port_enabled(bool p_enabled) { - ERR_FAIL_COND(!is_open()); - -// See comment above... -#ifdef WINDOWS_ENABLED -#define SO_REUSEPORT SO_REUSEADDR -#endif int par = p_enabled ? 1 : 0; - if (setsockopt(_sock, SOL_SOCKET, SO_REUSEPORT, SOCK_CBUF(&par), sizeof(int)) < 0) { - WARN_PRINT("Unable to set socket REUSEPORT option!"); + if (setsockopt(_sock, SOL_SOCKET, SO_REUSEADDR, &par, sizeof(int)) < 0) { + WARN_PRINT("Unable to set socket REUSEADDR option."); } } -bool NetSocketPosix::is_open() const { - return _sock != SOCK_EMPTY; +bool NetSocketUnix::is_open() const { + return _sock != -1; } -int NetSocketPosix::get_available_bytes() const { +int NetSocketUnix::get_available_bytes() const { ERR_FAIL_COND_V(!is_open(), -1); - SOCK_FIONREAD_LEN_TYPE len; - int ret = SOCK_IOCTL(_sock, FIONREAD, &len); + int len; + int ret = ioctl(_sock, FIONREAD, &len); if (ret == -1) { _get_socket_error(); print_verbose("Error when checking available bytes on socket."); @@ -754,7 +586,7 @@ int NetSocketPosix::get_available_bytes() const { return len; } -Error NetSocketPosix::get_socket_address(IPAddress *r_ip, uint16_t *r_port) const { +Error NetSocketUnix::get_socket_address(IPAddress *r_ip, uint16_t *r_port) const { ERR_FAIL_COND_V(!is_open(), FAILED); struct sockaddr_storage saddr; @@ -768,14 +600,14 @@ Error NetSocketPosix::get_socket_address(IPAddress *r_ip, uint16_t *r_port) cons return OK; } -Ref<NetSocket> NetSocketPosix::accept(IPAddress &r_ip, uint16_t &r_port) { +Ref<NetSocket> NetSocketUnix::accept(IPAddress &r_ip, uint16_t &r_port) { Ref<NetSocket> out; ERR_FAIL_COND_V(!is_open(), out); struct sockaddr_storage their_addr; socklen_t size = sizeof(their_addr); - SOCKET_TYPE fd = ::accept(_sock, (struct sockaddr *)&their_addr, &size); - if (fd == SOCK_EMPTY) { + int fd = ::accept(_sock, (struct sockaddr *)&their_addr, &size); + if (fd == -1) { _get_socket_error(); print_verbose("Error when accepting socket connection."); return out; @@ -783,18 +615,18 @@ Ref<NetSocket> NetSocketPosix::accept(IPAddress &r_ip, uint16_t &r_port) { _set_ip_port(&their_addr, &r_ip, &r_port); - NetSocketPosix *ns = memnew(NetSocketPosix); + NetSocketUnix *ns = memnew(NetSocketUnix); ns->_set_socket(fd, _ip_type, _is_stream); ns->set_blocking_enabled(false); return Ref<NetSocket>(ns); } -Error NetSocketPosix::join_multicast_group(const IPAddress &p_multi_address, const String &p_if_name) { +Error NetSocketUnix::join_multicast_group(const IPAddress &p_multi_address, const String &p_if_name) { return _change_multicast_group(p_multi_address, p_if_name, true); } -Error NetSocketPosix::leave_multicast_group(const IPAddress &p_multi_address, const String &p_if_name) { +Error NetSocketUnix::leave_multicast_group(const IPAddress &p_multi_address, const String &p_if_name) { return _change_multicast_group(p_multi_address, p_if_name, false); } -#endif // UNIX_SOCKET_UNAVAILABLE +#endif // UNIX_ENABLED && !UNIX_SOCKET_UNAVAILABLE diff --git a/drivers/unix/net_socket_posix.h b/drivers/unix/net_socket_unix.h index aa59ff36ee..08c45f2ac3 100644 --- a/drivers/unix/net_socket_posix.h +++ b/drivers/unix/net_socket_unix.h @@ -1,5 +1,5 @@ /**************************************************************************/ -/* net_socket_posix.h */ +/* net_socket_unix.h */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,25 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef NET_SOCKET_POSIX_H -#define NET_SOCKET_POSIX_H +#ifndef NET_SOCKET_UNIX_H +#define NET_SOCKET_UNIX_H -#include "core/io/net_socket.h" +#if defined(UNIX_ENABLED) && !defined(UNIX_SOCKET_UNAVAILABLE) -#if defined(WINDOWS_ENABLED) -#include <winsock2.h> -#include <ws2tcpip.h> -#define SOCKET_TYPE SOCKET +#include "core/io/net_socket.h" -#else #include <sys/socket.h> -#define SOCKET_TYPE int -#endif - -class NetSocketPosix : public NetSocket { +class NetSocketUnix : public NetSocket { private: - SOCKET_TYPE _sock; // NOLINT - the default value is defined in the .cpp + int _sock = -1; IP::Type _ip_type = IP::TYPE_NONE; bool _is_stream = false; @@ -61,7 +54,7 @@ private: }; NetError _get_socket_error() const; - void _set_socket(SOCKET_TYPE p_sock, IP::Type p_ip_type, bool p_is_stream); + void _set_socket(int p_sock, IP::Type p_ip_type, bool p_is_stream); _FORCE_INLINE_ Error _change_multicast_group(IPAddress p_ip, String p_if_name, bool p_add); _FORCE_INLINE_ void _set_close_exec_enabled(bool p_enabled); @@ -76,33 +69,34 @@ public: static void _set_ip_port(struct sockaddr_storage *p_addr, IPAddress *r_ip, uint16_t *r_port); static size_t _set_addr_storage(struct sockaddr_storage *p_addr, const IPAddress &p_ip, uint16_t p_port, IP::Type p_ip_type); - virtual Error open(Type p_sock_type, IP::Type &ip_type); - virtual void close(); - virtual Error bind(IPAddress p_addr, uint16_t p_port); - virtual Error listen(int p_max_pending); - virtual Error connect_to_host(IPAddress p_host, uint16_t p_port); - virtual Error poll(PollType p_type, int timeout) const; - virtual Error recv(uint8_t *p_buffer, int p_len, int &r_read); - virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IPAddress &r_ip, uint16_t &r_port, bool p_peek = false); - virtual Error send(const uint8_t *p_buffer, int p_len, int &r_sent); - virtual Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IPAddress p_ip, uint16_t p_port); - virtual Ref<NetSocket> accept(IPAddress &r_ip, uint16_t &r_port); - - virtual bool is_open() const; - virtual int get_available_bytes() const; - virtual Error get_socket_address(IPAddress *r_ip, uint16_t *r_port) const; - - virtual Error set_broadcasting_enabled(bool p_enabled); - virtual void set_blocking_enabled(bool p_enabled); - virtual void set_ipv6_only_enabled(bool p_enabled); - virtual void set_tcp_no_delay_enabled(bool p_enabled); - virtual void set_reuse_address_enabled(bool p_enabled); - virtual void set_reuse_port_enabled(bool p_enabled); - virtual Error join_multicast_group(const IPAddress &p_multi_address, const String &p_if_name); - virtual Error leave_multicast_group(const IPAddress &p_multi_address, const String &p_if_name); - - NetSocketPosix(); - ~NetSocketPosix(); + virtual Error open(Type p_sock_type, IP::Type &ip_type) override; + virtual void close() override; + virtual Error bind(IPAddress p_addr, uint16_t p_port) override; + virtual Error listen(int p_max_pending) override; + virtual Error connect_to_host(IPAddress p_host, uint16_t p_port) override; + virtual Error poll(PollType p_type, int timeout) const override; + virtual Error recv(uint8_t *p_buffer, int p_len, int &r_read) override; + virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IPAddress &r_ip, uint16_t &r_port, bool p_peek = false) override; + virtual Error send(const uint8_t *p_buffer, int p_len, int &r_sent) override; + virtual Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IPAddress p_ip, uint16_t p_port) override; + virtual Ref<NetSocket> accept(IPAddress &r_ip, uint16_t &r_port) override; + + virtual bool is_open() const override; + virtual int get_available_bytes() const override; + virtual Error get_socket_address(IPAddress *r_ip, uint16_t *r_port) const override; + + virtual Error set_broadcasting_enabled(bool p_enabled) override; + virtual void set_blocking_enabled(bool p_enabled) override; + virtual void set_ipv6_only_enabled(bool p_enabled) override; + virtual void set_tcp_no_delay_enabled(bool p_enabled) override; + virtual void set_reuse_address_enabled(bool p_enabled) override; + virtual Error join_multicast_group(const IPAddress &p_multi_address, const String &p_if_name) override; + virtual Error leave_multicast_group(const IPAddress &p_multi_address, const String &p_if_name) override; + + NetSocketUnix(); + ~NetSocketUnix() override; }; -#endif // NET_SOCKET_POSIX_H +#endif // UNIX_ENABLED && !UNIX_SOCKET_UNAVAILABLE + +#endif // NET_SOCKET_UNIX_H diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 8a9b130068..3976ae7d84 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -38,7 +38,7 @@ #include "drivers/unix/dir_access_unix.h" #include "drivers/unix/file_access_unix.h" #include "drivers/unix/file_access_unix_pipe.h" -#include "drivers/unix/net_socket_posix.h" +#include "drivers/unix/net_socket_unix.h" #include "drivers/unix/thread_posix.h" #include "servers/rendering_server.h" @@ -77,6 +77,7 @@ #include <stdlib.h> #include <string.h> #include <sys/resource.h> +#include <sys/stat.h> #include <sys/time.h> #include <sys/wait.h> #include <time.h> @@ -166,7 +167,9 @@ void OS_Unix::initialize_core() { DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_USERDATA); DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_FILESYSTEM); - NetSocketPosix::make_default(); +#ifndef UNIX_SOCKET_UNAVAILABLE + NetSocketUnix::make_default(); +#endif IPUnix::make_default(); process_map = memnew((HashMap<ProcessID, ProcessInfo>)); @@ -175,16 +178,96 @@ void OS_Unix::initialize_core() { void OS_Unix::finalize_core() { memdelete(process_map); - NetSocketPosix::cleanup(); +#ifndef UNIX_SOCKET_UNAVAILABLE + NetSocketUnix::cleanup(); +#endif } Vector<String> OS_Unix::get_video_adapter_driver_info() const { return Vector<String>(); } -String OS_Unix::get_stdin_string() { - char buff[1024]; - return String::utf8(fgets(buff, 1024, stdin)); +String OS_Unix::get_stdin_string(int64_t p_buffer_size) { + Vector<uint8_t> data; + data.resize(p_buffer_size); + if (fgets((char *)data.ptrw(), data.size(), stdin)) { + return String::utf8((char *)data.ptr()); + } + return String(); +} + +PackedByteArray OS_Unix::get_stdin_buffer(int64_t p_buffer_size) { + Vector<uint8_t> data; + data.resize(p_buffer_size); + size_t sz = fread((void *)data.ptrw(), 1, data.size(), stdin); + if (sz > 0) { + data.resize(sz); + return data; + } + return PackedByteArray(); +} + +OS_Unix::StdHandleType OS_Unix::get_stdin_type() const { + int h = fileno(stdin); + if (h == -1) { + return STD_HANDLE_INVALID; + } + + if (isatty(h)) { + return STD_HANDLE_CONSOLE; + } + struct stat statbuf; + if (fstat(h, &statbuf) < 0) { + return STD_HANDLE_UNKNOWN; + } + if (S_ISFIFO(statbuf.st_mode)) { + return STD_HANDLE_PIPE; + } else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) { + return STD_HANDLE_FILE; + } + return STD_HANDLE_UNKNOWN; +} + +OS_Unix::StdHandleType OS_Unix::get_stdout_type() const { + int h = fileno(stdout); + if (h == -1) { + return STD_HANDLE_INVALID; + } + + if (isatty(h)) { + return STD_HANDLE_CONSOLE; + } + struct stat statbuf; + if (fstat(h, &statbuf) < 0) { + return STD_HANDLE_UNKNOWN; + } + if (S_ISFIFO(statbuf.st_mode)) { + return STD_HANDLE_PIPE; + } else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) { + return STD_HANDLE_FILE; + } + return STD_HANDLE_UNKNOWN; +} + +OS_Unix::StdHandleType OS_Unix::get_stderr_type() const { + int h = fileno(stderr); + if (h == -1) { + return STD_HANDLE_INVALID; + } + + if (isatty(h)) { + return STD_HANDLE_CONSOLE; + } + struct stat statbuf; + if (fstat(h, &statbuf) < 0) { + return STD_HANDLE_UNKNOWN; + } + if (S_ISFIFO(statbuf.st_mode)) { + return STD_HANDLE_PIPE; + } else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) { + return STD_HANDLE_FILE; + } + return STD_HANDLE_UNKNOWN; } Error OS_Unix::get_entropy(uint8_t *r_buffer, int p_bytes) { diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index 3add5df055..2c7920c142 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -58,7 +58,11 @@ public: virtual Vector<String> get_video_adapter_driver_info() const override; - virtual String get_stdin_string() override; + virtual String get_stdin_string(int64_t p_buffer_size = 1024) override; + virtual PackedByteArray get_stdin_buffer(int64_t p_buffer_size = 1024) override; + virtual StdHandleType get_stdin_type() const override; + virtual StdHandleType get_stdout_type() const override; + virtual StdHandleType get_stderr_type() const override; virtual Error get_entropy(uint8_t *r_buffer, int p_bytes) override; diff --git a/drivers/vulkan/rendering_device_driver_vulkan.cpp b/drivers/vulkan/rendering_device_driver_vulkan.cpp index 6eecd850f5..a86f72e0b9 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.cpp +++ b/drivers/vulkan/rendering_device_driver_vulkan.cpp @@ -3032,13 +3032,10 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue, #if defined(SWAPPY_FRAME_PACING_ENABLED) if (swappy_frame_pacer_enable) { - const double max_fps = Engine::get_singleton()->get_max_fps(); - const uint64_t max_time = max_fps > 0 ? uint64_t((1000.0 * 1000.0 * 1000.0) / max_fps) : 0; - SwappyVk_initAndGetRefreshCycleDuration(get_jni_env(), static_cast<OS_Android *>(OS::get_singleton())->get_godot_java()->get_activity(), physical_device, vk_device, swap_chain->vk_swapchain, &swap_chain->refresh_duration); SwappyVk_setWindow(vk_device, swap_chain->vk_swapchain, static_cast<OS_Android *>(OS::get_singleton())->get_native_window()); - SwappyVk_setSwapIntervalNS(vk_device, swap_chain->vk_swapchain, MAX(swap_chain->refresh_duration, max_time)); + SwappyVk_setSwapIntervalNS(vk_device, swap_chain->vk_swapchain, swap_chain->refresh_duration); enum SwappyModes { PIPELINE_FORCED_ON, diff --git a/drivers/windows/net_socket_winsock.cpp b/drivers/windows/net_socket_winsock.cpp new file mode 100644 index 0000000000..3fe7fc619e --- /dev/null +++ b/drivers/windows/net_socket_winsock.cpp @@ -0,0 +1,613 @@ +/**************************************************************************/ +/* net_socket_winsock.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifdef WINDOWS_ENABLED + +#include "net_socket_winsock.h" + +#include <winsock2.h> +#include <ws2tcpip.h> + +#include <mswsock.h> +// Workaround missing flag in MinGW +#if defined(__MINGW32__) && !defined(SIO_UDP_NETRESET) +#define SIO_UDP_NETRESET _WSAIOW(IOC_VENDOR, 15) +#endif + +size_t NetSocketWinSock::_set_addr_storage(struct sockaddr_storage *p_addr, const IPAddress &p_ip, uint16_t p_port, IP::Type p_ip_type) { + memset(p_addr, 0, sizeof(struct sockaddr_storage)); + if (p_ip_type == IP::TYPE_IPV6 || p_ip_type == IP::TYPE_ANY) { // IPv6 socket. + + // IPv6 only socket with IPv4 address. + ERR_FAIL_COND_V(!p_ip.is_wildcard() && p_ip_type == IP::TYPE_IPV6 && p_ip.is_ipv4(), 0); + + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)p_addr; + addr6->sin6_family = AF_INET6; + addr6->sin6_port = htons(p_port); + if (p_ip.is_valid()) { + memcpy(&addr6->sin6_addr.s6_addr, p_ip.get_ipv6(), 16); + } else { + addr6->sin6_addr = in6addr_any; + } + return sizeof(sockaddr_in6); + } else { // IPv4 socket. + + // IPv4 socket with IPv6 address. + ERR_FAIL_COND_V(!p_ip.is_wildcard() && !p_ip.is_ipv4(), 0); + + struct sockaddr_in *addr4 = (struct sockaddr_in *)p_addr; + addr4->sin_family = AF_INET; + addr4->sin_port = htons(p_port); // Short, network byte order. + + if (p_ip.is_valid()) { + memcpy(&addr4->sin_addr.s_addr, p_ip.get_ipv4(), 4); + } else { + addr4->sin_addr.s_addr = INADDR_ANY; + } + + return sizeof(sockaddr_in); + } +} + +void NetSocketWinSock::_set_ip_port(struct sockaddr_storage *p_addr, IPAddress *r_ip, uint16_t *r_port) { + if (p_addr->ss_family == AF_INET) { + struct sockaddr_in *addr4 = (struct sockaddr_in *)p_addr; + if (r_ip) { + r_ip->set_ipv4((uint8_t *)&(addr4->sin_addr.s_addr)); + } + if (r_port) { + *r_port = ntohs(addr4->sin_port); + } + } else if (p_addr->ss_family == AF_INET6) { + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)p_addr; + if (r_ip) { + r_ip->set_ipv6(addr6->sin6_addr.s6_addr); + } + if (r_port) { + *r_port = ntohs(addr6->sin6_port); + } + } +} + +NetSocket *NetSocketWinSock::_create_func() { + return memnew(NetSocketWinSock); +} + +void NetSocketWinSock::make_default() { + ERR_FAIL_COND(_create != nullptr); + + WSADATA data; + WSAStartup(MAKEWORD(2, 2), &data); + _create = _create_func; +} + +void NetSocketWinSock::cleanup() { + ERR_FAIL_COND(_create == nullptr); + + WSACleanup(); + _create = nullptr; +} + +NetSocketWinSock::NetSocketWinSock() { +} + +NetSocketWinSock::~NetSocketWinSock() { + close(); +} + +NetSocketWinSock::NetError NetSocketWinSock::_get_socket_error() const { + int err = WSAGetLastError(); + if (err == WSAEISCONN) { + return ERR_NET_IS_CONNECTED; + } + if (err == WSAEINPROGRESS || err == WSAEALREADY) { + return ERR_NET_IN_PROGRESS; + } + if (err == WSAEWOULDBLOCK) { + return ERR_NET_WOULD_BLOCK; + } + if (err == WSAEADDRINUSE || err == WSAEADDRNOTAVAIL) { + return ERR_NET_ADDRESS_INVALID_OR_UNAVAILABLE; + } + if (err == WSAEACCES) { + return ERR_NET_UNAUTHORIZED; + } + if (err == WSAEMSGSIZE || err == WSAENOBUFS) { + return ERR_NET_BUFFER_TOO_SMALL; + } + print_verbose("Socket error: " + itos(err) + "."); + return ERR_NET_OTHER; +} + +bool NetSocketWinSock::_can_use_ip(const IPAddress &p_ip, const bool p_for_bind) const { + if (p_for_bind && !(p_ip.is_valid() || p_ip.is_wildcard())) { + return false; + } else if (!p_for_bind && !p_ip.is_valid()) { + return false; + } + // Check if socket support this IP type. + IP::Type type = p_ip.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6; + return !(_ip_type != IP::TYPE_ANY && !p_ip.is_wildcard() && _ip_type != type); +} + +_FORCE_INLINE_ Error NetSocketWinSock::_change_multicast_group(IPAddress p_ip, String p_if_name, bool p_add) { + ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); + ERR_FAIL_COND_V(!_can_use_ip(p_ip, false), ERR_INVALID_PARAMETER); + + // Need to force level and af_family to IP(v4) when using dual stacking and provided multicast group is IPv4. + IP::Type type = _ip_type == IP::TYPE_ANY && p_ip.is_ipv4() ? IP::TYPE_IPV4 : _ip_type; + // This needs to be the proper level for the multicast group, no matter if the socket is dual stacking. + int level = type == IP::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; + int ret = -1; + + IPAddress if_ip; + uint32_t if_v6id = 0; + HashMap<String, IP::Interface_Info> if_info; + IP::get_singleton()->get_local_interfaces(&if_info); + for (KeyValue<String, IP::Interface_Info> &E : if_info) { + IP::Interface_Info &c = E.value; + if (c.name != p_if_name) { + continue; + } + + if_v6id = (uint32_t)c.index.to_int(); + if (type == IP::TYPE_IPV6) { + break; // IPv6 uses index. + } + + for (const IPAddress &F : c.ip_addresses) { + if (!F.is_ipv4()) { + continue; // Wrong IP type. + } + if_ip = F; + break; + } + break; + } + + if (level == IPPROTO_IP) { + ERR_FAIL_COND_V(!if_ip.is_valid(), ERR_INVALID_PARAMETER); + struct ip_mreq greq; + int sock_opt = p_add ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP; + memcpy(&greq.imr_multiaddr, p_ip.get_ipv4(), 4); + memcpy(&greq.imr_interface, if_ip.get_ipv4(), 4); + ret = setsockopt(_sock, level, sock_opt, (const char *)&greq, sizeof(greq)); + } else { + struct ipv6_mreq greq; + int sock_opt = p_add ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP; + memcpy(&greq.ipv6mr_multiaddr, p_ip.get_ipv6(), 16); + greq.ipv6mr_interface = if_v6id; + ret = setsockopt(_sock, level, sock_opt, (const char *)&greq, sizeof(greq)); + } + ERR_FAIL_COND_V(ret != 0, FAILED); + + return OK; +} + +void NetSocketWinSock::_set_socket(SOCKET p_sock, IP::Type p_ip_type, bool p_is_stream) { + _sock = p_sock; + _ip_type = p_ip_type; + _is_stream = p_is_stream; +} + +Error NetSocketWinSock::open(Type p_sock_type, IP::Type &ip_type) { + ERR_FAIL_COND_V(is_open(), ERR_ALREADY_IN_USE); + ERR_FAIL_COND_V(ip_type > IP::TYPE_ANY || ip_type < IP::TYPE_NONE, ERR_INVALID_PARAMETER); + + int family = ip_type == IP::TYPE_IPV4 ? AF_INET : AF_INET6; + int protocol = p_sock_type == TYPE_TCP ? IPPROTO_TCP : IPPROTO_UDP; + int type = p_sock_type == TYPE_TCP ? SOCK_STREAM : SOCK_DGRAM; + _sock = socket(family, type, protocol); + + if (_sock == INVALID_SOCKET && ip_type == IP::TYPE_ANY) { + // Careful here, changing the referenced parameter so the caller knows that we are using an IPv4 socket + // in place of a dual stack one, and further calls to _set_sock_addr will work as expected. + ip_type = IP::TYPE_IPV4; + family = AF_INET; + _sock = socket(family, type, protocol); + } + + ERR_FAIL_COND_V(_sock == INVALID_SOCKET, FAILED); + _ip_type = ip_type; + + if (family == AF_INET6) { + // Select IPv4 over IPv6 mapping. + set_ipv6_only_enabled(ip_type != IP::TYPE_ANY); + } + + if (protocol == IPPROTO_UDP) { + // Make sure to disable broadcasting for UDP sockets. + // Depending on the OS, this option might or might not be enabled by default. Let's normalize it. + set_broadcasting_enabled(false); + } + + _is_stream = p_sock_type == TYPE_TCP; + + if (!_is_stream) { + // Disable windows feature/bug reporting WSAECONNRESET/WSAENETRESET when + // recv/recvfrom and an ICMP reply was received from a previous send/sendto. + unsigned long disable = 0; + if (ioctlsocket(_sock, SIO_UDP_CONNRESET, &disable) == SOCKET_ERROR) { + print_verbose("Unable to turn off UDP WSAECONNRESET behavior on Windows."); + } + if (ioctlsocket(_sock, SIO_UDP_NETRESET, &disable) == SOCKET_ERROR) { + // This feature seems not to be supported on wine. + print_verbose("Unable to turn off UDP WSAENETRESET behavior on Windows."); + } + } + return OK; +} + +void NetSocketWinSock::close() { + if (_sock != INVALID_SOCKET) { + closesocket(_sock); + } + + _sock = INVALID_SOCKET; + _ip_type = IP::TYPE_NONE; + _is_stream = false; +} + +Error NetSocketWinSock::bind(IPAddress p_addr, uint16_t p_port) { + ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); + ERR_FAIL_COND_V(!_can_use_ip(p_addr, true), ERR_INVALID_PARAMETER); + + sockaddr_storage addr; + size_t addr_size = _set_addr_storage(&addr, p_addr, p_port, _ip_type); + + if (::bind(_sock, (struct sockaddr *)&addr, addr_size) != 0) { + NetError err = _get_socket_error(); + print_verbose("Failed to bind socket. Error: " + itos(err) + "."); + close(); + return ERR_UNAVAILABLE; + } + + return OK; +} + +Error NetSocketWinSock::listen(int p_max_pending) { + ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); + + if (::listen(_sock, p_max_pending) != 0) { + _get_socket_error(); + print_verbose("Failed to listen from socket."); + close(); + return FAILED; + } + + return OK; +} + +Error NetSocketWinSock::connect_to_host(IPAddress p_host, uint16_t p_port) { + ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); + ERR_FAIL_COND_V(!_can_use_ip(p_host, false), ERR_INVALID_PARAMETER); + + struct sockaddr_storage addr; + size_t addr_size = _set_addr_storage(&addr, p_host, p_port, _ip_type); + + if (::WSAConnect(_sock, (struct sockaddr *)&addr, addr_size, nullptr, nullptr, nullptr, nullptr) != 0) { + NetError err = _get_socket_error(); + + switch (err) { + // We are already connected. + case ERR_NET_IS_CONNECTED: + return OK; + // Still waiting to connect, try again in a while. + case ERR_NET_WOULD_BLOCK: + case ERR_NET_IN_PROGRESS: + return ERR_BUSY; + default: + print_verbose("Connection to remote host failed."); + close(); + return FAILED; + } + } + + return OK; +} + +Error NetSocketWinSock::poll(PollType p_type, int p_timeout) const { + ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); + + bool ready = false; + fd_set rd, wr, ex; + fd_set *rdp = nullptr; + fd_set *wrp = nullptr; + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&ex); + FD_SET(_sock, &ex); + struct timeval timeout = { p_timeout / 1000, (p_timeout % 1000) * 1000 }; + // For blocking operation, pass nullptr timeout pointer to select. + struct timeval *tp = nullptr; + if (p_timeout >= 0) { + // If timeout is non-negative, we want to specify the timeout instead. + tp = &timeout; + } + + switch (p_type) { + case POLL_TYPE_IN: + FD_SET(_sock, &rd); + rdp = &rd; + break; + case POLL_TYPE_OUT: + FD_SET(_sock, &wr); + wrp = ≀ + break; + case POLL_TYPE_IN_OUT: + FD_SET(_sock, &rd); + FD_SET(_sock, &wr); + rdp = &rd; + wrp = ≀ + } + // WSAPoll is broken: https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/. + int ret = select(1, rdp, wrp, &ex, tp); + + if (ret == SOCKET_ERROR) { + return FAILED; + } + + if (ret == 0) { + return ERR_BUSY; + } + + if (FD_ISSET(_sock, &ex)) { + _get_socket_error(); + print_verbose("Exception when polling socket."); + return FAILED; + } + + if (rdp && FD_ISSET(_sock, rdp)) { + ready = true; + } + if (wrp && FD_ISSET(_sock, wrp)) { + ready = true; + } + + return ready ? OK : ERR_BUSY; +} + +Error NetSocketWinSock::recv(uint8_t *p_buffer, int p_len, int &r_read) { + ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); + + r_read = ::recv(_sock, (char *)p_buffer, p_len, 0); + + if (r_read < 0) { + NetError err = _get_socket_error(); + if (err == ERR_NET_WOULD_BLOCK) { + return ERR_BUSY; + } + + if (err == ERR_NET_BUFFER_TOO_SMALL) { + return ERR_OUT_OF_MEMORY; + } + + return FAILED; + } + + return OK; +} + +Error NetSocketWinSock::recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IPAddress &r_ip, uint16_t &r_port, bool p_peek) { + ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); + + struct sockaddr_storage from; + socklen_t len = sizeof(struct sockaddr_storage); + memset(&from, 0, len); + + r_read = ::recvfrom(_sock, (char *)p_buffer, p_len, p_peek ? MSG_PEEK : 0, (struct sockaddr *)&from, &len); + + if (r_read < 0) { + NetError err = _get_socket_error(); + if (err == ERR_NET_WOULD_BLOCK) { + return ERR_BUSY; + } + + if (err == ERR_NET_BUFFER_TOO_SMALL) { + return ERR_OUT_OF_MEMORY; + } + + return FAILED; + } + + if (from.ss_family == AF_INET) { + struct sockaddr_in *sin_from = (struct sockaddr_in *)&from; + r_ip.set_ipv4((uint8_t *)&sin_from->sin_addr); + r_port = ntohs(sin_from->sin_port); + } else if (from.ss_family == AF_INET6) { + struct sockaddr_in6 *s6_from = (struct sockaddr_in6 *)&from; + r_ip.set_ipv6((uint8_t *)&s6_from->sin6_addr); + r_port = ntohs(s6_from->sin6_port); + } else { + // Unsupported socket family, should never happen. + ERR_FAIL_V(FAILED); + } + + return OK; +} + +Error NetSocketWinSock::send(const uint8_t *p_buffer, int p_len, int &r_sent) { + ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); + + int flags = 0; + r_sent = ::send(_sock, (const char *)p_buffer, p_len, flags); + + if (r_sent < 0) { + NetError err = _get_socket_error(); + if (err == ERR_NET_WOULD_BLOCK) { + return ERR_BUSY; + } + if (err == ERR_NET_BUFFER_TOO_SMALL) { + return ERR_OUT_OF_MEMORY; + } + + return FAILED; + } + + return OK; +} + +Error NetSocketWinSock::sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IPAddress p_ip, uint16_t p_port) { + ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); + + struct sockaddr_storage addr; + size_t addr_size = _set_addr_storage(&addr, p_ip, p_port, _ip_type); + r_sent = ::sendto(_sock, (const char *)p_buffer, p_len, 0, (struct sockaddr *)&addr, addr_size); + + if (r_sent < 0) { + NetError err = _get_socket_error(); + if (err == ERR_NET_WOULD_BLOCK) { + return ERR_BUSY; + } + if (err == ERR_NET_BUFFER_TOO_SMALL) { + return ERR_OUT_OF_MEMORY; + } + + return FAILED; + } + + return OK; +} + +Error NetSocketWinSock::set_broadcasting_enabled(bool p_enabled) { + ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED); + // IPv6 has no broadcast support. + if (_ip_type == IP::TYPE_IPV6) { + return ERR_UNAVAILABLE; + } + + int par = p_enabled ? 1 : 0; + if (setsockopt(_sock, SOL_SOCKET, SO_BROADCAST, (const char *)&par, sizeof(int)) != 0) { + WARN_PRINT("Unable to change broadcast setting."); + return FAILED; + } + return OK; +} + +void NetSocketWinSock::set_blocking_enabled(bool p_enabled) { + ERR_FAIL_COND(!is_open()); + + int ret = 0; + unsigned long par = p_enabled ? 0 : 1; + ret = ioctlsocket(_sock, FIONBIO, &par); + if (ret != 0) { + WARN_PRINT("Unable to change non-block mode."); + } +} + +void NetSocketWinSock::set_ipv6_only_enabled(bool p_enabled) { + ERR_FAIL_COND(!is_open()); + // This option is only available in IPv6 sockets. + ERR_FAIL_COND(_ip_type == IP::TYPE_IPV4); + + int par = p_enabled ? 1 : 0; + if (setsockopt(_sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&par, sizeof(int)) != 0) { + WARN_PRINT("Unable to change IPv4 address mapping over IPv6 option."); + } +} + +void NetSocketWinSock::set_tcp_no_delay_enabled(bool p_enabled) { + ERR_FAIL_COND(!is_open()); + ERR_FAIL_COND(!_is_stream); // Not TCP. + + int par = p_enabled ? 1 : 0; + if (setsockopt(_sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&par, sizeof(int)) < 0) { + WARN_PRINT("Unable to set TCP no delay option."); + } +} + +void NetSocketWinSock::set_reuse_address_enabled(bool p_enabled) { + ERR_FAIL_COND(!is_open()); + + // On Windows, enabling SO_REUSEADDR actually would also enable reuse port, very bad on TCP. Denying... + // Windows does not have this option, SO_REUSEADDR in this magical world means SO_REUSEPORT +} + +bool NetSocketWinSock::is_open() const { + return _sock != INVALID_SOCKET; +} + +int NetSocketWinSock::get_available_bytes() const { + ERR_FAIL_COND_V(!is_open(), -1); + + unsigned long len; + int ret = ioctlsocket(_sock, FIONREAD, &len); + if (ret == -1) { + _get_socket_error(); + print_verbose("Error when checking available bytes on socket."); + return -1; + } + return len; +} + +Error NetSocketWinSock::get_socket_address(IPAddress *r_ip, uint16_t *r_port) const { + ERR_FAIL_COND_V(!is_open(), FAILED); + + struct sockaddr_storage saddr; + socklen_t len = sizeof(saddr); + if (getsockname(_sock, (struct sockaddr *)&saddr, &len) != 0) { + _get_socket_error(); + print_verbose("Error when reading local socket address."); + return FAILED; + } + _set_ip_port(&saddr, r_ip, r_port); + return OK; +} + +Ref<NetSocket> NetSocketWinSock::accept(IPAddress &r_ip, uint16_t &r_port) { + Ref<NetSocket> out; + ERR_FAIL_COND_V(!is_open(), out); + + struct sockaddr_storage their_addr; + socklen_t size = sizeof(their_addr); + SOCKET fd = ::accept(_sock, (struct sockaddr *)&their_addr, &size); + if (fd == INVALID_SOCKET) { + _get_socket_error(); + print_verbose("Error when accepting socket connection."); + return out; + } + + _set_ip_port(&their_addr, &r_ip, &r_port); + + NetSocketWinSock *ns = memnew(NetSocketWinSock); + ns->_set_socket(fd, _ip_type, _is_stream); + ns->set_blocking_enabled(false); + return Ref<NetSocket>(ns); +} + +Error NetSocketWinSock::join_multicast_group(const IPAddress &p_multi_address, const String &p_if_name) { + return _change_multicast_group(p_multi_address, p_if_name, true); +} + +Error NetSocketWinSock::leave_multicast_group(const IPAddress &p_multi_address, const String &p_if_name) { + return _change_multicast_group(p_multi_address, p_if_name, false); +} + +#endif // WINDOWS_ENABLED diff --git a/drivers/windows/net_socket_winsock.h b/drivers/windows/net_socket_winsock.h new file mode 100644 index 0000000000..5c3445b8cb --- /dev/null +++ b/drivers/windows/net_socket_winsock.h @@ -0,0 +1,102 @@ +/**************************************************************************/ +/* net_socket_winsock.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef NET_SOCKET_WINSOCK_H +#define NET_SOCKET_WINSOCK_H + +#ifdef WINDOWS_ENABLED + +#include "core/io/net_socket.h" + +#include <winsock2.h> +#include <ws2tcpip.h> + +class NetSocketWinSock : public NetSocket { +private: + SOCKET _sock = INVALID_SOCKET; + IP::Type _ip_type = IP::TYPE_NONE; + bool _is_stream = false; + + enum NetError { + ERR_NET_WOULD_BLOCK, + ERR_NET_IS_CONNECTED, + ERR_NET_IN_PROGRESS, + ERR_NET_ADDRESS_INVALID_OR_UNAVAILABLE, + ERR_NET_UNAUTHORIZED, + ERR_NET_BUFFER_TOO_SMALL, + ERR_NET_OTHER, + }; + + NetError _get_socket_error() const; + void _set_socket(SOCKET p_sock, IP::Type p_ip_type, bool p_is_stream); + _FORCE_INLINE_ Error _change_multicast_group(IPAddress p_ip, String p_if_name, bool p_add); + +protected: + static NetSocket *_create_func(); + + bool _can_use_ip(const IPAddress &p_ip, const bool p_for_bind) const; + +public: + static void make_default(); + static void cleanup(); + static void _set_ip_port(struct sockaddr_storage *p_addr, IPAddress *r_ip, uint16_t *r_port); + static size_t _set_addr_storage(struct sockaddr_storage *p_addr, const IPAddress &p_ip, uint16_t p_port, IP::Type p_ip_type); + + virtual Error open(Type p_sock_type, IP::Type &ip_type) override; + virtual void close() override; + virtual Error bind(IPAddress p_addr, uint16_t p_port) override; + virtual Error listen(int p_max_pending) override; + virtual Error connect_to_host(IPAddress p_host, uint16_t p_port) override; + virtual Error poll(PollType p_type, int timeout) const override; + virtual Error recv(uint8_t *p_buffer, int p_len, int &r_read) override; + virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IPAddress &r_ip, uint16_t &r_port, bool p_peek = false) override; + virtual Error send(const uint8_t *p_buffer, int p_len, int &r_sent) override; + virtual Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IPAddress p_ip, uint16_t p_port) override; + virtual Ref<NetSocket> accept(IPAddress &r_ip, uint16_t &r_port) override; + + virtual bool is_open() const override; + virtual int get_available_bytes() const override; + virtual Error get_socket_address(IPAddress *r_ip, uint16_t *r_port) const override; + + virtual Error set_broadcasting_enabled(bool p_enabled) override; + virtual void set_blocking_enabled(bool p_enabled) override; + virtual void set_ipv6_only_enabled(bool p_enabled) override; + virtual void set_tcp_no_delay_enabled(bool p_enabled) override; + virtual void set_reuse_address_enabled(bool p_enabled) override; + virtual Error join_multicast_group(const IPAddress &p_multi_address, const String &p_if_name) override; + virtual Error leave_multicast_group(const IPAddress &p_multi_address, const String &p_if_name) override; + + NetSocketWinSock(); + ~NetSocketWinSock() override; +}; + +#endif // WINDOWS_ENABLED + +#endif // NET_SOCKET_WINSOCK_H diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 8d7c6a1f16..b923dc0732 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -1650,7 +1650,7 @@ void AnimationBezierTrackEdit::_zoom_callback(float p_zoom_factor, Vector2 p_ori Ref<InputEventWithModifiers> iewm = p_event; if (iewm.is_valid() && iewm->is_alt_pressed()) { // Alternate zoom (doesn't affect timeline). - timeline_v_zoom = CLAMP(timeline_v_zoom * p_zoom_factor, 0.000001, 100000); + timeline_v_zoom = CLAMP(timeline_v_zoom / p_zoom_factor, 0.000001, 100000); } else { float zoom_factor = p_zoom_factor > 1.0 ? AnimationTimelineEdit::SCROLL_ZOOM_FACTOR_IN : AnimationTimelineEdit::SCROLL_ZOOM_FACTOR_OUT; timeline->_zoom_callback(zoom_factor, p_origin, p_event); diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index bc79b14d4a..55ea7c0082 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -63,7 +63,6 @@ constexpr double FPS_DECIMAL = 1.0; constexpr double SECOND_DECIMAL = 0.0001; -constexpr double FPS_STEP_FRACTION = 0.0625; void AnimationTrackKeyEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_obj"), &AnimationTrackKeyEdit::_update_obj); @@ -3776,6 +3775,7 @@ void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim, bool p_re step->set_read_only(false); snap_keys->set_disabled(false); snap_timeline->set_disabled(false); + fps_compat->set_disabled(false); snap_mode->set_disabled(false); auto_fit->set_disabled(false); auto_fit_bezier->set_disabled(false); @@ -3798,6 +3798,7 @@ void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim, bool p_re step->set_read_only(true); snap_keys->set_disabled(true); snap_timeline->set_disabled(true); + fps_compat->set_disabled(true); snap_mode->set_disabled(true); bezier_edit_icon->set_disabled(true); auto_fit->set_disabled(true); @@ -5029,7 +5030,12 @@ void AnimationTrackEditor::_snap_mode_changed(int p_mode) { } marker_edit->set_use_fps(use_fps); // To ensure that the conversion results are consistent between serialization and load, the value is snapped with 0.0625 to be a rational number when FPS mode is used. - step->set_step(use_fps ? FPS_STEP_FRACTION : SECOND_DECIMAL); + step->set_step(use_fps ? FPS_DECIMAL : SECOND_DECIMAL); + if (use_fps) { + fps_compat->hide(); + } else { + fps_compat->show(); + } _update_step_spinbox(); } @@ -5045,7 +5051,6 @@ void AnimationTrackEditor::_update_step_spinbox() { } else { step->set_value(1.0 / animation->get_step()); } - } else { step->set_value(animation->get_step()); } @@ -5054,6 +5059,20 @@ void AnimationTrackEditor::_update_step_spinbox() { _update_snap_unit(); } +void AnimationTrackEditor::_update_fps_compat_mode(bool p_enabled) { + _update_snap_unit(); +} + +void AnimationTrackEditor::_update_nearest_fps_label() { + bool is_fps_invalid = nearest_fps == 0; + if (is_fps_invalid) { + nearest_fps_label->hide(); + } else { + nearest_fps_label->show(); + nearest_fps_label->set_text("Nearest FPS: " + itos(nearest_fps)); + } +} + void AnimationTrackEditor::_animation_update() { timeline->queue_redraw(); timeline->update_values(); @@ -5115,6 +5134,7 @@ void AnimationTrackEditor::_notification(int p_what) { bezier_edit_icon->set_button_icon(get_editor_theme_icon(SNAME("EditBezier"))); snap_timeline->set_button_icon(get_editor_theme_icon(SNAME("SnapTimeline"))); snap_keys->set_button_icon(get_editor_theme_icon(SNAME("SnapKeys"))); + fps_compat->set_button_icon(get_editor_theme_icon(SNAME("FPS"))); view_group->set_button_icon(get_editor_theme_icon(view_group->is_pressed() ? SNAME("AnimationTrackList") : SNAME("AnimationTrackGroup"))); selected_filter->set_button_icon(get_editor_theme_icon(SNAME("AnimationFilter"))); imported_anim_warning->set_button_icon(get_editor_theme_icon(SNAME("NodeWarning"))); @@ -5160,9 +5180,8 @@ void AnimationTrackEditor::_update_step(double p_new_step) { double step_value = p_new_step; if (timeline->is_using_fps()) { if (step_value != 0.0) { - // step_value must also be less than or equal to 1000 to ensure that no error accumulates due to interactions with retrieving values from inner range. + // A step_value should be less than or equal to 1000 to ensure that no error accumulates due to interactions with retrieving values from inner range. step_value = 1.0 / MIN(1000.0, p_new_step); - ; } timeline->queue_redraw(); } @@ -7336,39 +7355,55 @@ void AnimationTrackEditor::_selection_changed() { } void AnimationTrackEditor::_update_snap_unit() { + nearest_fps = 0; + if (step->get_value() <= 0) { snap_unit = 0; + _update_nearest_fps_label(); return; // Avoid zero div. } if (timeline->is_using_fps()) { + _clear_selection(true); // Needs to recreate a spinbox of the KeyEdit. snap_unit = 1.0 / step->get_value(); } else { - double integer; - double fraction = Math::modf(step->get_value(), &integer); - fraction = 1.0 / Math::round(1.0 / fraction); - snap_unit = integer + fraction; + if (fps_compat->is_pressed()) { + snap_unit = CLAMP(step->get_value(), 0.0, 1.0); + if (!Math::is_zero_approx(snap_unit)) { + real_t fps = Math::round(1.0 / snap_unit); + nearest_fps = int(fps); + snap_unit = 1.0 / fps; + } + } else { + snap_unit = step->get_value(); + } } + _update_nearest_fps_label(); } float AnimationTrackEditor::snap_time(float p_value, bool p_relative) { if (is_snap_keys_enabled()) { + double current_snap = snap_unit; if (Input::get_singleton()->is_key_pressed(Key::SHIFT)) { // Use more precise snapping when holding Shift. - snap_unit *= 0.25; + current_snap *= 0.25; } if (p_relative) { - double rel = Math::fmod(timeline->get_value(), snap_unit); - p_value = Math::snapped(p_value + rel, snap_unit) - rel; + double rel = Math::fmod(timeline->get_value(), current_snap); + p_value = Math::snapped(p_value + rel, current_snap) - rel; } else { - p_value = Math::snapped(p_value, snap_unit); + p_value = Math::snapped(p_value, current_snap); } } return p_value; } +float AnimationTrackEditor::get_snap_unit() { + return snap_unit; +} + void AnimationTrackEditor::_show_imported_anim_warning() { // It looks terrible on a single line but the TTR extractor doesn't support line breaks yet. EditorNode::get_singleton()->show_warning( @@ -7622,6 +7657,18 @@ AnimationTrackEditor::AnimationTrackEditor() { snap_keys->set_pressed(true); snap_keys->set_tooltip_text(TTR("Apply snapping to selected key(s).")); + fps_compat = memnew(Button); + fps_compat->set_flat(true); + bottom_hb->add_child(fps_compat); + fps_compat->set_disabled(true); + fps_compat->set_toggle_mode(true); + fps_compat->set_pressed(true); + fps_compat->set_tooltip_text(TTR("Apply snapping to the nearest integer FPS.")); + fps_compat->connect(SceneStringName(toggled), callable_mp(this, &AnimationTrackEditor::_update_fps_compat_mode)); + + nearest_fps_label = memnew(Label); + bottom_hb->add_child(nearest_fps_label); + step = memnew(EditorSpinSlider); step->set_min(0); step->set_max(1000000); diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index 1053468452..e7271f1941 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -600,6 +600,8 @@ class AnimationTrackEditor : public VBoxContainer { AnimationMarkerEdit *marker_edit = nullptr; HSlider *zoom = nullptr; EditorSpinSlider *step = nullptr; + Button *fps_compat = nullptr; + Label *nearest_fps_label = nullptr; TextureRect *zoom_icon = nullptr; Button *snap_keys = nullptr; Button *snap_timeline = nullptr; @@ -637,6 +639,8 @@ class AnimationTrackEditor : public VBoxContainer { void _track_grab_focus(int p_track); void _update_scroll(double); + void _update_nearest_fps_label(); + void _update_fps_compat_mode(bool p_enabled); void _update_step(double p_new_step); void _update_length(double p_new_len); void _dropped_track(int p_from_track, int p_to_track); @@ -853,6 +857,8 @@ class AnimationTrackEditor : public VBoxContainer { void _pick_track_select_recursive(TreeItem *p_item, const String &p_filter, Vector<Node *> &p_select_candidates); double snap_unit; + bool fps_compatible = true; + int nearest_fps = 0; void _update_snap_unit(); protected: @@ -935,6 +941,7 @@ public: bool can_add_reset_key() const; float get_moving_selection_offset() const; float snap_time(float p_value, bool p_relative = false); + float get_snap_unit(); bool is_grouping_tracks(); PackedStringArray get_selected_section() const; bool is_marker_selected(const StringName &p_marker) const; diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 558eed98c6..b5306154ba 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -1259,6 +1259,15 @@ void EditorFileSystem::_process_file_system(const ScannedDirectory *p_scan_dir, } } } + + if (fi->uid == ResourceUID::INVALID_ID && ResourceLoader::exists(path) && !ResourceLoader::has_custom_uid_support(path) && !FileAccess::exists(path + ".uid")) { + // Create a UID. + Ref<FileAccess> f = FileAccess::open(path + ".uid", FileAccess::WRITE); + if (f.is_valid()) { + fi->uid = ResourceUID::get_singleton()->create_id(); + f->store_line(ResourceUID::get_singleton()->id_to_text(fi->uid)); + } + } } if (fi->uid != ResourceUID::INVALID_ID) { @@ -1507,6 +1516,9 @@ void EditorFileSystem::_delete_internal_files(const String &p_file) { } da->remove(p_file + ".import"); } + if (FileAccess::exists(p_file + ".uid")) { + DirAccess::remove_absolute(p_file + ".uid"); + } } int EditorFileSystem::_insert_actions_delete_files_directory(EditorFileSystemDirectory *p_dir) { @@ -2740,13 +2752,17 @@ Error EditorFileSystem::_reimport_file(const String &p_file, const HashMap<Strin } } + if (uid == ResourceUID::INVALID_ID) { + uid = ResourceUID::get_singleton()->create_id(); + } + //finally, perform import!! String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(p_file); List<String> import_variants; List<String> gen_files; Variant meta; - Error err = importer->import(p_file, base_path, params, &import_variants, &gen_files, &meta); + Error err = importer->import(uid, p_file, base_path, params, &import_variants, &gen_files, &meta); // As import is complete, save the .import file. @@ -2767,10 +2783,6 @@ Error EditorFileSystem::_reimport_file(const String &p_file, const HashMap<Strin f->store_line("type=\"" + importer->get_resource_type() + "\""); } - if (uid == ResourceUID::INVALID_ID) { - uid = ResourceUID::get_singleton()->create_id(); - } - f->store_line("uid=\"" + ResourceUID::get_singleton()->id_to_text(uid) + "\""); // Store in readable format. if (err == OK) { diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp index d11bf7720c..b0c06475f8 100644 --- a/editor/editor_help_search.cpp +++ b/editor/editor_help_search.cpp @@ -151,7 +151,7 @@ void EditorHelpSearch::_update_results() { search_flags |= SEARCH_SHOW_HIERARCHY; } - search = Ref<Runner>(memnew(Runner(results_tree, results_tree, &tree_cache, term, search_flags))); + search.instantiate(results_tree, results_tree, &tree_cache, term, search_flags); // Clear old search flags to force rebuild on short term. old_search_flags = 0; @@ -162,7 +162,7 @@ void EditorHelpSearch::_update_results() { hierarchy_button->set_disabled(true); // Always show hierarchy for short searches. - search = Ref<Runner>(memnew(Runner(results_tree, results_tree, &tree_cache, term, search_flags | SEARCH_SHOW_HIERARCHY))); + search.instantiate(results_tree, results_tree, &tree_cache, term, search_flags | SEARCH_SHOW_HIERARCHY); old_search_flags = search_flags; set_process(true); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 91dd8e5019..1c23ce8ede 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -931,10 +931,19 @@ float EditorProperty::get_name_split_ratio() const { return split_ratio; } +void EditorProperty::set_favoritable(bool p_favoritable) { + can_favorite = p_favoritable; +} + +bool EditorProperty::is_favoritable() const { + return can_favorite; +} + void EditorProperty::set_object_and_property(Object *p_object, const StringName &p_property) { object = p_object; property = p_property; - _update_pin_flags(); + + _update_flags(); } static bool _is_value_potential_override(Node *p_node, const String &p_property) { @@ -953,12 +962,14 @@ static bool _is_value_potential_override(Node *p_node, const String &p_property) } } -void EditorProperty::_update_pin_flags() { +void EditorProperty::_update_flags() { can_pin = false; pin_hidden = true; + if (read_only) { return; } + if (Node *node = Object::cast_to<Node>(object)) { // Avoid errors down the road by ignoring nodes which are not part of a scene if (!node->get_owner()) { @@ -1034,6 +1045,10 @@ void EditorProperty::menu_option(int p_option) { case MENU_COPY_PROPERTY_PATH: { DisplayServer::get_singleton()->clipboard_set(property_path); } break; + case MENU_FAVORITE_PROPERTY: { + emit_signal(SNAME("property_favorited"), property, !favorited); + queue_redraw(); + } break; case MENU_PIN_VALUE: { emit_signal(SNAME("property_pinned"), property, !pinned); queue_redraw(); @@ -1091,6 +1106,7 @@ void EditorProperty::_bind_methods() { ADD_SIGNAL(MethodInfo("property_deleted", PropertyInfo(Variant::STRING_NAME, "property"))); ADD_SIGNAL(MethodInfo("property_keyed_with_value", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); ADD_SIGNAL(MethodInfo("property_checked", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::BOOL, "checked"))); + ADD_SIGNAL(MethodInfo("property_favorited", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::BOOL, "favorited"))); ADD_SIGNAL(MethodInfo("property_pinned", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::BOOL, "pinned"))); ADD_SIGNAL(MethodInfo("property_can_revert_changed", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::BOOL, "can_revert"))); ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"))); @@ -1129,8 +1145,21 @@ void EditorProperty::_update_popup() { menu->set_item_disabled(MENU_PASTE_VALUE, is_read_only()); menu->set_item_disabled(MENU_COPY_PROPERTY_PATH, internal); - if (!pin_hidden) { + if (can_favorite || !pin_hidden) { menu->add_separator(); + } + + if (can_favorite) { + if (favorited) { + menu->add_icon_item(get_editor_theme_icon(SNAME("Unfavorite")), TTR("Unfavorite Property"), MENU_FAVORITE_PROPERTY); + menu->set_item_tooltip(menu->get_item_index(MENU_FAVORITE_PROPERTY), TTR("Make this property be put back at its original place.")); + } else { + menu->add_icon_item(get_editor_theme_icon(SNAME("Favorites")), TTR("Favorite Property"), MENU_FAVORITE_PROPERTY); + menu->set_item_tooltip(menu->get_item_index(MENU_FAVORITE_PROPERTY), TTR("Make this property be placed at the top for all objects of this class.")); + } + } + + if (!pin_hidden) { if (can_pin) { menu->add_icon_check_item(get_editor_theme_icon(SNAME("Pin")), TTR("Pin Value"), MENU_PIN_VALUE); menu->set_item_checked(menu->get_item_index(MENU_PIN_VALUE), pinned); @@ -1219,9 +1248,14 @@ void EditorInspectorPlugin::_bind_methods() { void EditorInspectorCategory::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - menu->set_item_icon(menu->get_item_index(MENU_OPEN_DOCS), get_editor_theme_icon(SNAME("Help"))); + if (menu) { + if (is_favorite) { + menu->set_item_icon(menu->get_item_index(EditorInspector::MENU_UNFAVORITE_ALL), get_editor_theme_icon(SNAME("Unfavorite"))); + } else { + menu->set_item_icon(menu->get_item_index(MENU_OPEN_DOCS), get_editor_theme_icon(SNAME("Help"))); + } + } } break; case NOTIFICATION_DRAW: { Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg")); @@ -1278,6 +1312,15 @@ Control *EditorInspectorCategory::make_custom_tooltip(const String &p_text) cons return memnew(Control); // Make the standard tooltip invisible. } +void EditorInspectorCategory::set_as_favorite(EditorInspector *p_for_inspector) { + is_favorite = true; + + menu = memnew(PopupMenu); + menu->add_item(TTR("Unfavorite All"), EditorInspector::MENU_UNFAVORITE_ALL); + add_child(menu); + menu->connect(SceneStringName(id_pressed), callable_mp(p_for_inspector, &EditorInspector::_handle_menu_option)); +} + Size2 EditorInspectorCategory::get_minimum_size() const { Ref<Font> font = get_theme_font(SNAME("bold"), EditorStringName(EditorFonts)); int font_size = get_theme_font_size(SNAME("bold_size"), EditorStringName(EditorFonts)); @@ -1306,7 +1349,7 @@ void EditorInspectorCategory::_handle_menu_option(int p_option) { } void EditorInspectorCategory::gui_input(const Ref<InputEvent> &p_event) { - if (doc_class_name.is_empty()) { + if (!is_favorite && doc_class_name.is_empty()) { return; } @@ -1315,20 +1358,21 @@ void EditorInspectorCategory::gui_input(const Ref<InputEvent> &p_event) { return; } - menu->set_item_disabled(menu->get_item_index(MENU_OPEN_DOCS), !EditorHelp::get_doc_data()->class_list.has(doc_class_name)); + if (!is_favorite) { + if (!menu) { + menu = memnew(PopupMenu); + menu->add_icon_item(get_editor_theme_icon(SNAME("Help")), TTR("Open Documentation"), MENU_OPEN_DOCS); + add_child(menu); + menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorInspectorCategory::_handle_menu_option)); + } + menu->set_item_disabled(menu->get_item_index(MENU_OPEN_DOCS), !EditorHelp::get_doc_data()->class_list.has(doc_class_name)); + } menu->set_position(get_screen_position() + mb_event->get_position()); menu->reset_size(); menu->popup(); } -EditorInspectorCategory::EditorInspectorCategory() { - menu = memnew(PopupMenu); - menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorInspectorCategory::_handle_menu_option)); - menu->add_item(TTR("Open Documentation"), MENU_OPEN_DOCS); - add_child(menu); -} - //////////////////////////////////////////////// //////////////////////////////////////////////// @@ -1622,6 +1666,10 @@ void EditorInspectorSection::gui_input(const Ref<InputEvent> &p_event) { } } +String EditorInspectorSection::get_section() const { + return section; +} + VBoxContainer *EditorInspectorSection::get_vbox() { return vbox; } @@ -2675,7 +2723,13 @@ String EditorInspector::get_selected_path() const { void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, EditorInspectorSection *p_section, Ref<EditorInspectorPlugin> ped) { for (const EditorInspectorPlugin::AddedEditor &F : ped->added_editors) { EditorProperty *ep = Object::cast_to<EditorProperty>(F.property_editor); - current_vbox->add_child(F.property_editor); + + if (ep && current_favorites.has(F.properties[0])) { + ep->favorited = true; + favorites_vbox->add_child(F.property_editor); + } else { + current_vbox->add_child(F.property_editor); + } if (ep) { ep->object = object; @@ -2684,6 +2738,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, EditorIn ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), CONNECT_DEFERRED); ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value)); ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked)); + ep->connect("property_favorited", callable_mp(this, &EditorInspector::_set_property_favorited), CONNECT_DEFERRED); ep->connect("property_pinned", callable_mp(this, &EditorInspector::_property_pinned)); ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected)); ep->connect("multiple_properties_changed", callable_mp(this, &EditorInspector::_multiple_properties_changed)); @@ -2727,7 +2782,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, EditorIn ep->set_read_only(read_only); ep->update_property(); - ep->_update_pin_flags(); + ep->_update_flags(); ep->update_editor_property_status(); ep->set_deletable(deletable_properties); ep->update_cache(); @@ -2837,6 +2892,7 @@ void EditorInspector::update_tree() { String subgroup; String subgroup_base; int section_depth = 0; + bool disable_favorite = false; VBoxContainer *category_vbox = nullptr; List<PropertyInfo> plist; @@ -2844,13 +2900,17 @@ void EditorInspector::update_tree() { HashMap<VBoxContainer *, HashMap<String, VBoxContainer *>> vbox_per_path; HashMap<String, EditorInspectorArray *> editor_inspector_array_per_prefix; + HashMap<String, HashMap<String, LocalVector<EditorProperty *>>> favorites_to_add; Color sscolor = get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)); // Get the lists of editors to add the beginning. for (Ref<EditorInspectorPlugin> &ped : valid_plugins) { ped->parse_begin(object); - _parse_added_editors(main_vbox, nullptr, ped); + _parse_added_editors(begin_vbox, nullptr, ped); + } + if (begin_vbox->get_child_count()) { + begin_vbox->show(); } StringName doc_name; @@ -2897,6 +2957,7 @@ void EditorInspector::update_tree() { subgroup = ""; subgroup_base = ""; section_depth = 0; + disable_favorite = false; vbox_per_path.clear(); editor_inspector_array_per_prefix.clear(); @@ -2960,6 +3021,11 @@ void EditorInspector::update_tree() { } else { category_icon = EditorNode::get_singleton()->get_object_icon(scr.ptr(), "Object"); } + + // Property favorites aren't compatible with built-in scripts. + if (scr->is_built_in()) { + disable_favorite = true; + } } } @@ -3058,6 +3124,11 @@ void EditorInspector::update_tree() { } } + // Don't allow to favorite array items. + if (!disable_favorite) { + disable_favorite = !array_prefix.is_empty(); + } + if (!array_prefix.is_empty()) { path = path.trim_prefix(array_prefix); int char_index = path.find("/"); @@ -3449,6 +3520,7 @@ void EditorInspector::update_tree() { ep->set_draw_warning(draw_warning); ep->set_use_folding(use_folding); + ep->set_favoritable(can_favorite && !disable_favorite); ep->set_checkable(checkable); ep->set_checked(checked); ep->set_keying(keying); @@ -3456,7 +3528,12 @@ void EditorInspector::update_tree() { ep->set_deletable(deletable_properties || p.name.begins_with("metadata/")); } - current_vbox->add_child(editors[i].property_editor); + if (ep && ep->is_favoritable() && current_favorites.has(p.name)) { + ep->favorited = true; + favorites_to_add[group][subgroup].push_back(ep); + } else { + current_vbox->add_child(editors[i].property_editor); + } if (ep) { // Eventually, set other properties/signals after the property editor got added to the tree. @@ -3465,6 +3542,7 @@ void EditorInspector::update_tree() { ep->connect("property_keyed", callable_mp(this, &EditorInspector::_property_keyed)); ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), CONNECT_DEFERRED); ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value)); + ep->connect("property_favorited", callable_mp(this, &EditorInspector::_set_property_favorited), CONNECT_DEFERRED); ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked)); ep->connect("property_pinned", callable_mp(this, &EditorInspector::_property_pinned)); ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected)); @@ -3495,7 +3573,7 @@ void EditorInspector::update_tree() { ep->set_internal(p.usage & PROPERTY_USAGE_INTERNAL); ep->update_property(); - ep->_update_pin_flags(); + ep->_update_flags(); ep->update_editor_property_status(); ep->update_cache(); @@ -3506,6 +3584,79 @@ void EditorInspector::update_tree() { } } + if (!current_favorites.is_empty()) { + favorites_section->show(); + + // Organize the favorited properties in their sections, to keep context and differentiate from others with the same name. + bool is_localized = property_name_style == EditorPropertyNameProcessor::STYLE_LOCALIZED; + for (const KeyValue<String, HashMap<String, LocalVector<EditorProperty *>>> &KV : favorites_to_add) { + String section_name = KV.key; + String label; + String tooltip; + VBoxContainer *parent_vbox = favorites_vbox; + if (!section_name.is_empty()) { + if (is_localized) { + label = EditorPropertyNameProcessor::get_singleton()->translate_group_name(section_name); + tooltip = section_name; + } else { + label = section_name; + tooltip = EditorPropertyNameProcessor::get_singleton()->translate_group_name(section_name); + } + + EditorInspectorSection *section = memnew(EditorInspectorSection); + favorites_groups_vbox->add_child(section); + parent_vbox = section->get_vbox(); + section->setup("", section_name, object, sscolor, false); + section->set_tooltip_text(tooltip); + } + + for (const KeyValue<String, LocalVector<EditorProperty *>> &KV2 : KV.value) { + section_name = KV2.key; + VBoxContainer *vbox = parent_vbox; + if (!section_name.is_empty()) { + if (is_localized) { + label = EditorPropertyNameProcessor::get_singleton()->translate_group_name(section_name); + tooltip = section_name; + } else { + label = section_name; + tooltip = EditorPropertyNameProcessor::get_singleton()->translate_group_name(section_name); + } + + EditorInspectorSection *section = memnew(EditorInspectorSection); + vbox->add_child(section); + vbox = section->get_vbox(); + section->setup("", section_name, object, sscolor, false); + section->set_tooltip_text(tooltip); + } + + for (EditorProperty *ep : KV2.value) { + vbox->add_child(ep); + } + } + } + + // Show a separator if there's no category to clearly divide the properties. + favorites_separator->hide(); + if (main_vbox->get_child_count() > 0) { + EditorInspectorCategory *category = Object::cast_to<EditorInspectorCategory>(main_vbox->get_child(0)); + if (!category) { + favorites_separator->show(); + } + } + + // Clean up empty sections. + for (List<EditorInspectorSection *>::Element *I = sections.back(); I; I = I->prev()) { + EditorInspectorSection *section = I->get(); + if (section->get_vbox()->get_child_count() == 0) { + I = I->prev(); + + sections.erase(section); + vbox_per_path[main_vbox].erase(section->get_section()); + memdelete(section); + } + } + } + if (!hide_metadata && !object->call("_hide_metadata_from_inspector")) { // Add 4px of spacing between the "Add Metadata" button and the content above it. Control *spacer = memnew(Control); @@ -3548,6 +3699,19 @@ void EditorInspector::update_property(const String &p_prop) { } void EditorInspector::_clear(bool p_hide_plugins) { + begin_vbox->hide(); + while (begin_vbox->get_child_count()) { + memdelete(begin_vbox->get_child(0)); + } + + favorites_section->hide(); + while (favorites_vbox->get_child_count()) { + memdelete(favorites_vbox->get_child(0)); + } + while (favorites_groups_vbox->get_child_count()) { + memdelete(favorites_groups_vbox->get_child(0)); + } + while (main_vbox->get_child_count()) { memdelete(main_vbox->get_child(0)); } @@ -3594,6 +3758,10 @@ void EditorInspector::edit(Object *p_object) { update_scroll_request = scroll_cache[object->get_instance_id()]; //done this way because wait until full size is accommodated } object->connect(CoreStringName(property_list_changed), callable_mp(this, &EditorInspector::_changed_callback)); + + can_favorite = Object::cast_to<Node>(object) || Object::cast_to<Resource>(object); + _update_current_favorites(); + update_tree(); } @@ -4088,10 +4256,164 @@ void EditorInspector::_node_removed(Node *p_node) { } } +void EditorInspector::_update_current_favorites() { + current_favorites.clear(); + if (!can_favorite) { + return; + } + + HashMap<String, PackedStringArray> favorites = EditorSettings::get_singleton()->get_favorite_properties(); + + // Fetch script properties. + Ref<Script> scr = object->get_script(); + if (scr.is_valid()) { + List<PropertyInfo> plist; + // FIXME: Only properties from a saved script will be available, unsaved ones will be ignored. + // Can cause a little wonkiness, while nothing serious, would be nice to find a way to get + // unsaved ones without needing to get the entire property list of an object. + scr->get_script_property_list(&plist); + + String path; + HashMap<String, LocalVector<String>> props; + + for (PropertyInfo &p : plist) { + if (p.usage & PROPERTY_USAGE_CATEGORY) { + path = favorites.has(p.hint_string) ? p.hint_string : String(); + } else if (p.usage & PROPERTY_USAGE_SCRIPT_VARIABLE && !path.is_empty()) { + props[path].push_back(p.name); + } + } + + // Add favorited properties while removing invalid ones. + bool invalid_props = false; + for (const KeyValue<String, LocalVector<String>> &KV : props) { + path = KV.key; + for (int i = 0; i < favorites[path].size(); i++) { + String prop = favorites[path][i]; + if (KV.value.has(prop)) { + current_favorites.append(prop); + } else { + invalid_props = true; + favorites[path].erase(prop); + i--; + } + } + + if (favorites[path].is_empty()) { + favorites.erase(path); + } + } + + if (invalid_props) { + EditorSettings::get_singleton()->set_favorite_properties(favorites); + } + } + + // Fetch built-in properties. + StringName class_name = object->get_class_name(); + for (const KeyValue<String, PackedStringArray> &KV : favorites) { + if (ClassDB::is_parent_class(class_name, KV.key)) { + current_favorites.append_array(KV.value); + } + } +} + +void EditorInspector::_set_property_favorited(const String &p_path, bool p_favorited) { + if (!object) { + return; + } + + StringName class_name = object->get_class_name(); + while (!class_name.is_empty()) { + bool has_prop = ClassDB::has_property(class_name, p_path, true); + if (has_prop) { + break; + } + + class_name = ClassDB::get_parent_class_nocheck(class_name); + } + + if (class_name.is_empty()) { + Ref<Script> scr = object->get_script(); + if (scr.is_valid()) { + List<PropertyInfo> plist; + scr->get_script_property_list(&plist); + + String path; + for (PropertyInfo &p : plist) { + if (p.usage & PROPERTY_USAGE_CATEGORY) { + path = p.hint_string; + } else if (p.usage & PROPERTY_USAGE_SCRIPT_VARIABLE && p.name == p_path) { + class_name = path; + break; + } + } + } + + ERR_FAIL_COND_MSG(class_name.is_empty(), "Can't favorite invalid property. If said property was from a script and recently renamed, try saving it first."); + } + + HashMap<String, PackedStringArray> favorites = EditorSettings::get_singleton()->get_favorite_properties(); + if (p_favorited) { + current_favorites.append(p_path); + favorites[class_name].append(p_path); + } else { + current_favorites.erase(p_path); + + if (favorites.has(class_name) && favorites[class_name].has(p_path)) { + if (favorites[class_name].size() > 1) { + favorites[class_name].erase(p_path); + } else { + favorites.erase(class_name); + } + } + } + EditorSettings::get_singleton()->set_favorite_properties(favorites); + + update_tree(); +} + +void EditorInspector::_clear_current_favorites() { + current_favorites.clear(); + + HashMap<String, PackedStringArray> favorites = EditorSettings::get_singleton()->get_favorite_properties(); + + Ref<Script> scr = object->get_script(); + if (scr.is_valid()) { + List<PropertyInfo> plist; + scr->get_script_property_list(&plist); + + for (PropertyInfo &p : plist) { + if (p.usage & PROPERTY_USAGE_CATEGORY && favorites.has(p.hint_string)) { + favorites.erase(p.hint_string); + } + } + } + + StringName class_name = object->get_class_name(); + while (class_name) { + if (favorites.has(class_name)) { + favorites.erase(class_name); + } + + class_name = ClassDB::get_parent_class(class_name); + } + + EditorSettings::get_singleton()->set_favorite_properties(favorites); + update_tree(); +} + void EditorInspector::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { - main_vbox->add_theme_constant_override("separation", get_theme_constant(SNAME("v_separation"), SNAME("EditorInspector"))); + favorites_category->icon = get_editor_theme_icon(SNAME("Favorites")); + + int separation = get_theme_constant(SNAME("v_separation"), SNAME("EditorInspector")); + base_vbox->add_theme_constant_override("separation", separation); + begin_vbox->add_theme_constant_override("separation", separation); + favorites_section->add_theme_constant_override("separation", separation); + favorites_groups_vbox->add_theme_constant_override("separation", separation); + main_vbox->add_theme_constant_override("separation", separation); } break; case NOTIFICATION_READY: { @@ -4189,6 +4511,7 @@ void EditorInspector::_notification(int p_what) { void EditorInspector::_changed_callback() { //this is called when property change is notified via notify_property_list_changed() if (object != nullptr) { + _update_current_favorites(); _edit_request_change(object, String()); } } @@ -4278,6 +4601,14 @@ void EditorInspector::_add_meta_confirm() { undo_redo->commit_action(); } +void EditorInspector::_handle_menu_option(int p_option) { + switch (p_option) { + case MENU_UNFAVORITE_ALL: + _clear_current_favorites(); + break; + } +} + void EditorInspector::_bind_methods() { ClassDB::bind_method("_edit_request_change", &EditorInspector::_edit_request_change); ClassDB::bind_method("get_selected_path", &EditorInspector::get_selected_path); @@ -4296,9 +4627,36 @@ void EditorInspector::_bind_methods() { EditorInspector::EditorInspector() { object = nullptr; + + base_vbox = memnew(VBoxContainer); + base_vbox->set_h_size_flags(SIZE_EXPAND_FILL); + add_child(base_vbox); + + begin_vbox = memnew(VBoxContainer); + base_vbox->add_child(begin_vbox); + begin_vbox->hide(); + + favorites_section = memnew(VBoxContainer); + base_vbox->add_child(favorites_section); + favorites_section->hide(); + + favorites_category = memnew(EditorInspectorCategory); + favorites_category->set_as_favorite(this); + favorites_section->add_child(favorites_category); + favorites_category->label = TTR("Favorites"); + + favorites_vbox = memnew(VBoxContainer); + favorites_section->add_child(favorites_vbox); + favorites_groups_vbox = memnew(VBoxContainer); + favorites_section->add_child(favorites_groups_vbox); + + favorites_separator = memnew(HSeparator); + favorites_section->add_child(favorites_separator); + favorites_separator->hide(); + main_vbox = memnew(VBoxContainer); - main_vbox->set_h_size_flags(SIZE_EXPAND_FILL); - add_child(main_vbox); + base_vbox->add_child(main_vbox); + set_horizontal_scroll_mode(SCROLL_MODE_DISABLED); set_follow_focus(true); diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index 0309213b76..2e4633ccea 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -41,6 +41,7 @@ class Button; class ConfirmationDialog; class EditorInspector; class EditorValidationPanel; +class HSeparator; class LineEdit; class MarginContainer; class OptionButton; @@ -64,6 +65,7 @@ public: MENU_COPY_VALUE, MENU_PASTE_VALUE, MENU_COPY_PROPERTY_PATH, + MENU_FAVORITE_PROPERTY, MENU_PIN_VALUE, MENU_OPEN_DOCUMENTATION, }; @@ -112,6 +114,9 @@ private: bool pin_hidden = false; bool pinned = false; + bool can_favorite = false; + bool favorited = false; + bool use_folding = false; bool draw_top_bg = true; @@ -134,7 +139,7 @@ private: GDVIRTUAL0(_update_property) GDVIRTUAL1(_set_read_only, bool) - void _update_pin_flags(); + void _update_flags(); protected: bool has_borders = false; @@ -218,6 +223,9 @@ public: void set_name_split_ratio(float p_ratio); float get_name_split_ratio() const; + void set_favoritable(bool p_favoritable); + bool is_favoritable() const; + void set_object_and_property(Object *p_object, const StringName &p_property); virtual Control *make_custom_tooltip(const String &p_text) const override; @@ -285,6 +293,7 @@ class EditorInspectorCategory : public Control { String label; String doc_class_name; PopupMenu *menu = nullptr; + bool is_favorite = false; void _handle_menu_option(int p_option); @@ -293,10 +302,10 @@ protected: virtual void gui_input(const Ref<InputEvent> &p_event) override; public: + void set_as_favorite(EditorInspector *p_for_inspector); + virtual Size2 get_minimum_size() const override; virtual Control *make_custom_tooltip(const String &p_text) const override; - - EditorInspectorCategory(); }; class EditorInspectorSection : public Container { @@ -331,6 +340,7 @@ public: virtual Size2 get_minimum_size() const override; void setup(const String &p_section, const String &p_label, Object *p_object, const Color &p_bg_color, bool p_foldable, int p_indent_depth = 0, int p_level = 1); + String get_section() const; VBoxContainer *get_vbox(); void unfold(); void fold(); @@ -480,13 +490,31 @@ public: class EditorInspector : public ScrollContainer { GDCLASS(EditorInspector, ScrollContainer); + friend class EditorInspectorCategory; + enum { MAX_PLUGINS = 1024 }; static Ref<EditorInspectorPlugin> inspector_plugins[MAX_PLUGINS]; static int inspector_plugin_count; + // Right-click context menu options. + enum ClassMenuOption { + MENU_UNFAVORITE_ALL, + }; + + bool can_favorite = false; + PackedStringArray current_favorites; + VBoxContainer *favorites_section = nullptr; + EditorInspectorCategory *favorites_category = nullptr; + VBoxContainer *favorites_vbox = nullptr; + VBoxContainer *favorites_groups_vbox = nullptr; + HSeparator *favorites_separator = nullptr; + EditorInspector *root_inspector = nullptr; + + VBoxContainer *base_vbox = nullptr; + VBoxContainer *begin_vbox = nullptr; VBoxContainer *main_vbox = nullptr; // Map used to cache the instantiated editors. @@ -557,6 +585,10 @@ class EditorInspector : public ScrollContainer { void _property_selected(const String &p_path, int p_focusable); void _object_id_selected(const String &p_path, ObjectID p_id); + void _update_current_favorites(); + void _set_property_favorited(const String &p_path, bool p_favorited); + void _clear_current_favorites(); + void _node_removed(Node *p_node); HashMap<StringName, int> per_array_page; @@ -584,6 +616,8 @@ class EditorInspector : public ScrollContainer { void _add_meta_confirm(); void _show_add_meta_dialog(); + void _handle_menu_option(int p_option); + protected: static void _bind_methods(); void _notification(int p_what); diff --git a/editor/editor_interface.cpp b/editor/editor_interface.cpp index 264c80dcbf..e85258df50 100644 --- a/editor/editor_interface.cpp +++ b/editor/editor_interface.cpp @@ -43,6 +43,7 @@ #include "editor/gui/editor_quick_open_dialog.h" #include "editor/gui/editor_run_bar.h" #include "editor/gui/editor_scene_tabs.h" +#include "editor/gui/editor_toaster.h" #include "editor/gui/scene_tree_editor.h" #include "editor/inspector_dock.h" #include "editor/plugins/node_3d_editor_plugin.h" @@ -89,6 +90,10 @@ Ref<EditorSettings> EditorInterface::get_editor_settings() const { return EditorSettings::get_singleton(); } +EditorToaster *EditorInterface::get_editor_toaster() const { + return EditorToaster::get_singleton(); +} + EditorUndoRedoManager *EditorInterface::get_editor_undo_redo() const { return EditorUndoRedoManager::get_singleton(); } @@ -280,14 +285,10 @@ void EditorInterface::set_current_feature_profile(const String &p_profile_name) // Editor dialogs. void EditorInterface::popup_node_selector(const Callable &p_callback, const TypedArray<StringName> &p_valid_types, Node *p_current_value) { - // TODO: Should reuse dialog instance instead of creating a fresh one, but need to rework set_valid_types first. - if (node_selector) { - node_selector->disconnect(SNAME("selected"), callable_mp(this, &EditorInterface::_node_selected).bind(p_callback)); - node_selector->disconnect(SNAME("canceled"), callable_mp(this, &EditorInterface::_node_selection_canceled).bind(p_callback)); - get_base_control()->remove_child(node_selector); - node_selector->queue_free(); + if (!node_selector) { + node_selector = memnew(SceneTreeDialog); + get_base_control()->add_child(node_selector); } - node_selector = memnew(SceneTreeDialog); Vector<StringName> valid_types; int length = p_valid_types.size(); @@ -296,27 +297,18 @@ void EditorInterface::popup_node_selector(const Callable &p_callback, const Type valid_types.write[i] = p_valid_types[i]; } node_selector->set_valid_types(valid_types); - - get_base_control()->add_child(node_selector); - node_selector->popup_scenetree_dialog(p_current_value); - const Callable selected_callback = callable_mp(this, &EditorInterface::_node_selected).bind(p_callback); - node_selector->connect(SNAME("selected"), selected_callback, CONNECT_DEFERRED); - - const Callable canceled_callback = callable_mp(this, &EditorInterface::_node_selection_canceled).bind(p_callback); - node_selector->connect(SNAME("canceled"), canceled_callback, CONNECT_DEFERRED); + const Callable callback = callable_mp(this, &EditorInterface::_node_selected); + node_selector->connect(SNAME("selected"), callback.bind(p_callback), CONNECT_DEFERRED); + node_selector->connect(SNAME("canceled"), callback.bind(NodePath(), p_callback), CONNECT_DEFERRED); } void EditorInterface::popup_property_selector(Object *p_object, const Callable &p_callback, const PackedInt32Array &p_type_filter, const String &p_current_value) { - // TODO: Should reuse dialog instance instead of creating a fresh one, but need to rework set_type_filter first. - if (property_selector) { - property_selector->disconnect(SNAME("selected"), callable_mp(this, &EditorInterface::_property_selected).bind(p_callback)); - property_selector->disconnect(SNAME("canceled"), callable_mp(this, &EditorInterface::_property_selection_canceled).bind(p_callback)); - get_base_control()->remove_child(property_selector); - property_selector->queue_free(); + if (!property_selector) { + property_selector = memnew(PropertySelector); + get_base_control()->add_child(property_selector); } - property_selector = memnew(PropertySelector); Vector<Variant::Type> type_filter; int length = p_type_filter.size(); @@ -325,16 +317,24 @@ void EditorInterface::popup_property_selector(Object *p_object, const Callable & type_filter.write[i] = (Variant::Type)p_type_filter[i]; } property_selector->set_type_filter(type_filter); + property_selector->select_property_from_instance(p_object, p_current_value); - get_base_control()->add_child(property_selector); + const Callable callback = callable_mp(this, &EditorInterface::_property_selected); + property_selector->connect(SNAME("selected"), callback.bind(p_callback), CONNECT_DEFERRED); + property_selector->connect(SNAME("canceled"), callback.bind(String(), p_callback), CONNECT_DEFERRED); +} - property_selector->select_property_from_instance(p_object, p_current_value); +void EditorInterface::popup_method_selector(Object *p_object, const Callable &p_callback, const String &p_current_value) { + if (!method_selector) { + method_selector = memnew(PropertySelector); + get_base_control()->add_child(method_selector); + } - const Callable selected_callback = callable_mp(this, &EditorInterface::_property_selected).bind(p_callback); - property_selector->connect(SNAME("selected"), selected_callback, CONNECT_DEFERRED); + method_selector->select_method_from_instance(p_object, p_current_value); - const Callable canceled_callback = callable_mp(this, &EditorInterface::_property_selection_canceled).bind(p_callback); - property_selector->connect(SNAME("canceled"), canceled_callback, CONNECT_DEFERRED); + const Callable callback = callable_mp(this, &EditorInterface::_method_selected); + method_selector->connect(SNAME("selected"), callback.bind(p_callback), CONNECT_DEFERRED); + method_selector->connect(SNAME("canceled"), callback.bind(String(), p_callback), CONNECT_DEFERRED); } void EditorInterface::popup_quick_open(const Callable &p_callback, const TypedArray<StringName> &p_base_types) { @@ -356,20 +356,40 @@ void EditorInterface::popup_quick_open(const Callable &p_callback, const TypedAr } void EditorInterface::_node_selected(const NodePath &p_node_path, const Callable &p_callback) { - const NodePath path = get_edited_scene_root()->get_path().rel_path_to(p_node_path); - _call_dialog_callback(p_callback, path, "node selected"); -} + const Callable callback = callable_mp(this, &EditorInterface::_node_selected); + node_selector->disconnect(SNAME("selected"), callback); + node_selector->disconnect(SNAME("canceled"), callback); -void EditorInterface::_node_selection_canceled(const Callable &p_callback) { - _call_dialog_callback(p_callback, NodePath(), "node selection canceled"); + if (p_node_path.is_empty()) { + _call_dialog_callback(p_callback, NodePath(), "node selection canceled"); + } else { + const NodePath path = get_edited_scene_root()->get_path().rel_path_to(p_node_path); + _call_dialog_callback(p_callback, path, "node selected"); + } } void EditorInterface::_property_selected(const String &p_property_name, const Callable &p_callback) { - _call_dialog_callback(p_callback, NodePath(p_property_name).get_as_property_path(), "property selected"); + const Callable callback = callable_mp(this, &EditorInterface::_property_selected); + property_selector->disconnect(SNAME("selected"), callback); + property_selector->disconnect(SNAME("canceled"), callback); + + if (p_property_name.is_empty()) { + _call_dialog_callback(p_callback, NodePath(p_property_name).get_as_property_path(), "property selection canceled"); + } else { + _call_dialog_callback(p_callback, NodePath(p_property_name).get_as_property_path(), "property selected"); + } } -void EditorInterface::_property_selection_canceled(const Callable &p_callback) { - _call_dialog_callback(p_callback, NodePath(), "property selection canceled"); +void EditorInterface::_method_selected(const String &p_method_name, const Callable &p_callback) { + const Callable callback = callable_mp(this, &EditorInterface::_method_selected); + method_selector->disconnect(SNAME("selected"), callback); + method_selector->disconnect(SNAME("canceled"), callback); + + if (p_method_name.is_empty()) { + _call_dialog_callback(p_callback, p_method_name, "method selection canceled"); + } else { + _call_dialog_callback(p_callback, p_method_name, "method selected"); + } } void EditorInterface::_quick_open(const String &p_file_path, const Callable &p_callback) { @@ -556,6 +576,7 @@ void EditorInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("get_resource_previewer"), &EditorInterface::get_resource_previewer); ClassDB::bind_method(D_METHOD("get_selection"), &EditorInterface::get_selection); ClassDB::bind_method(D_METHOD("get_editor_settings"), &EditorInterface::get_editor_settings); + ClassDB::bind_method(D_METHOD("get_editor_toaster"), &EditorInterface::get_editor_toaster); ClassDB::bind_method(D_METHOD("get_editor_undo_redo"), &EditorInterface::get_editor_undo_redo); ClassDB::bind_method(D_METHOD("make_mesh_previews", "meshes", "preview_size"), &EditorInterface::_make_mesh_previews); @@ -593,6 +614,7 @@ void EditorInterface::_bind_methods() { ClassDB::bind_method(D_METHOD("popup_node_selector", "callback", "valid_types", "current_value"), &EditorInterface::popup_node_selector, DEFVAL(TypedArray<StringName>()), DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("popup_property_selector", "object", "callback", "type_filter", "current_value"), &EditorInterface::popup_property_selector, DEFVAL(PackedInt32Array()), DEFVAL(String())); + ClassDB::bind_method(D_METHOD("popup_method_selector", "object", "callback", "current_value"), &EditorInterface::popup_method_selector, DEFVAL(String())); ClassDB::bind_method(D_METHOD("popup_quick_open", "callback", "base_types"), &EditorInterface::popup_quick_open, DEFVAL(TypedArray<StringName>())); // Editor docks. diff --git a/editor/editor_interface.h b/editor/editor_interface.h index 4877444dac..2ae77331b1 100644 --- a/editor/editor_interface.h +++ b/editor/editor_interface.h @@ -45,6 +45,7 @@ class EditorPlugin; class EditorResourcePreview; class EditorSelection; class EditorSettings; +class EditorToaster; class EditorUndoRedoManager; class FileSystemDock; class Mesh; @@ -66,12 +67,12 @@ class EditorInterface : public Object { // Editor dialogs. PropertySelector *property_selector = nullptr; + PropertySelector *method_selector = nullptr; SceneTreeDialog *node_selector = nullptr; void _node_selected(const NodePath &p_node_paths, const Callable &p_callback); - void _node_selection_canceled(const Callable &p_callback); void _property_selected(const String &p_property_name, const Callable &p_callback); - void _property_selection_canceled(const Callable &p_callback); + void _method_selected(const String &p_property_name, const Callable &p_callback); void _quick_open(const String &p_file_path, const Callable &p_callback); void _call_dialog_callback(const Callable &p_callback, const Variant &p_selected, const String &p_context); @@ -102,6 +103,7 @@ public: EditorResourcePreview *get_resource_previewer() const; EditorSelection *get_selection() const; Ref<EditorSettings> get_editor_settings() const; + EditorToaster *get_editor_toaster() const; EditorUndoRedoManager *get_editor_undo_redo() const; Vector<Ref<Texture2D>> make_mesh_previews(const Vector<Ref<Mesh>> &p_meshes, Vector<Transform3D> *p_transforms, int p_preview_size); @@ -139,6 +141,7 @@ public: void popup_node_selector(const Callable &p_callback, const TypedArray<StringName> &p_valid_types = TypedArray<StringName>(), Node *p_current_value = nullptr); // Must use Vector<int> because exposing Vector<Variant::Type> is not supported. void popup_property_selector(Object *p_object, const Callable &p_callback, const PackedInt32Array &p_type_filter = PackedInt32Array(), const String &p_current_value = String()); + void popup_method_selector(Object *p_object, const Callable &p_callback, const String &p_current_value = String()); void popup_quick_open(const Callable &p_callback, const TypedArray<StringName> &p_base_types = TypedArray<StringName>()); // Editor docks. diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 36b43b7e9b..0df062c508 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1454,6 +1454,16 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String file->popup_file_dialog(); } +void EditorNode::ensure_uid_file(const String &p_new_resource_path) { + if (ResourceLoader::exists(p_new_resource_path) && !ResourceLoader::has_custom_uid_support(p_new_resource_path) && !FileAccess::exists(p_new_resource_path + ".uid")) { + Ref<FileAccess> f = FileAccess::open(p_new_resource_path + ".uid", FileAccess::WRITE); + if (f.is_valid()) { + const ResourceUID::ID id = ResourceUID::get_singleton()->create_id(); + f->store_line(ResourceUID::get_singleton()->id_to_text(id)); + } + } +} + void EditorNode::_menu_option(int p_option) { _menu_option_confirm(p_option, false); } @@ -2153,7 +2163,7 @@ void EditorNode::_dialog_action(String p_file) { } if (ml.is_null()) { - ml = Ref<MeshLibrary>(memnew(MeshLibrary)); + ml.instantiate(); } MeshLibraryEditor::update_library_file(editor_data.get_edited_scene_root(), ml, merge_with_existing_library, apply_mesh_instance_transforms); @@ -2173,6 +2183,12 @@ void EditorNode::_dialog_action(String p_file) { case RESOURCE_SAVE_AS: { ERR_FAIL_COND(saving_resource.is_null()); save_resource_in_path(saving_resource, p_file); + + if (current_menu_option == RESOURCE_SAVE_AS) { + // Create .uid file when making new Resource. + ensure_uid_file(p_file); + } + saving_resource = Ref<Resource>(); ObjectID current_id = editor_history.get_current(); Object *current_obj = current_id.is_valid() ? ObjectDB::get_instance(current_id) : nullptr; diff --git a/editor/editor_node.h b/editor/editor_node.h index 49c1699c28..4a283983c8 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -747,6 +747,7 @@ public: void save_resource_in_path(const Ref<Resource> &p_resource, const String &p_path); void save_resource(const Ref<Resource> &p_resource); void save_resource_as(const Ref<Resource> &p_resource, const String &p_at_path = String()); + void ensure_uid_file(const String &p_new_resource_path); void show_about() { _menu_option_confirm(HELP_ABOUT, false); } diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index ce75efa462..bdb5ed2ed9 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -462,10 +462,26 @@ void EditorPropertyPath::_set_read_only(bool p_read_only) { } void EditorPropertyPath::_path_selected(const String &p_path) { - emit_changed(get_edited_property(), p_path); + String full_path = p_path; + ResourceUID::ID id = ResourceLoader::get_resource_uid(full_path); + + if (id != ResourceUID::INVALID_ID) { + full_path = ResourceUID::get_singleton()->id_to_text(id); + } + + emit_changed(get_edited_property(), full_path); update_property(); } +String EditorPropertyPath::_get_path_text() { + String full_path = get_edited_property_value(); + if (full_path.begins_with("uid://")) { + full_path = ResourceUID::get_singleton()->get_id_path(ResourceUID::get_singleton()->text_to_id(full_path)); + } + + return full_path; +} + void EditorPropertyPath::_path_pressed() { if (!dialog) { dialog = memnew(EditorFileDialog); @@ -474,7 +490,7 @@ void EditorPropertyPath::_path_pressed() { add_child(dialog); } - String full_path = get_edited_property_value(); + String full_path = _get_path_text(); dialog->clear_filters(); @@ -502,7 +518,7 @@ void EditorPropertyPath::_path_pressed() { } void EditorPropertyPath::update_property() { - String full_path = get_edited_property_value(); + String full_path = _get_path_text(); path->set_text(full_path); path->set_tooltip_text(full_path); } @@ -547,8 +563,7 @@ void EditorPropertyPath::_drop_data_fw(const Point2 &p_point, const Variant &p_d return; } - emit_changed(get_edited_property(), filesPaths[0]); - update_property(); + _path_selected(filesPaths[0]); } bool EditorPropertyPath::_can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 9cc72cd5c5..ae9c454195 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -142,6 +142,8 @@ class EditorPropertyPath : public EditorProperty { LineEdit *path = nullptr; Button *path_edit = nullptr; + String _get_path_text(); + void _path_selected(const String &p_path); void _path_pressed(); void _path_focus_exited(); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index eeb8ceb1ed..b0d1c3e6bb 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -715,6 +715,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("text_editor/script_list/sort_members_outline_alphabetically", false, true); _initial_set("text_editor/script_list/script_temperature_enabled", true); _initial_set("text_editor/script_list/script_temperature_history_size", 15); + _initial_set("text_editor/script_list/highlight_scene_scripts", true); _initial_set("text_editor/script_list/group_help_pages", true); EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "text_editor/script_list/sort_scripts_by", 0, "Name,Path,None"); EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "text_editor/script_list/list_script_names_as", 0, "Name,Parent Directory And Name,Full Path"); @@ -1229,7 +1230,7 @@ fail: extra_config->set_value("init_projects", "list", list); } - singleton = Ref<EditorSettings>(memnew(EditorSettings)); + singleton.instantiate(); singleton->set_path(config_file_path, true); singleton->save_changed_setting = true; singleton->_load_defaults(extra_config); @@ -1496,10 +1497,26 @@ void EditorSettings::set_favorites(const Vector<String> &p_favorites) { } } +void EditorSettings::set_favorite_properties(const HashMap<String, PackedStringArray> &p_favorite_properties) { + favorite_properties = p_favorite_properties; + String favorite_properties_file = EditorPaths::get_singleton()->get_project_settings_dir().path_join("favorite_properties"); + + Ref<ConfigFile> cf; + cf.instantiate(); + for (const KeyValue<String, PackedStringArray> &kv : p_favorite_properties) { + cf->set_value(kv.key, "properties", kv.value); + } + cf->save(favorite_properties_file); +} + Vector<String> EditorSettings::get_favorites() const { return favorites; } +HashMap<String, PackedStringArray> EditorSettings::get_favorite_properties() const { + return favorite_properties; +} + void EditorSettings::set_recent_dirs(const Vector<String> &p_recent_dirs) { recent_dirs = p_recent_dirs; String recent_dirs_file; @@ -1522,23 +1539,51 @@ Vector<String> EditorSettings::get_recent_dirs() const { void EditorSettings::load_favorites_and_recent_dirs() { String favorites_file; + String favorite_properties_file; String recent_dirs_file; if (Engine::get_singleton()->is_project_manager_hint()) { favorites_file = EditorPaths::get_singleton()->get_config_dir().path_join("favorite_dirs"); + favorite_properties_file = EditorPaths::get_singleton()->get_config_dir().path_join("favorite_properties"); recent_dirs_file = EditorPaths::get_singleton()->get_config_dir().path_join("recent_dirs"); } else { favorites_file = EditorPaths::get_singleton()->get_project_settings_dir().path_join("favorites"); + favorite_properties_file = EditorPaths::get_singleton()->get_project_settings_dir().path_join("favorite_properties"); recent_dirs_file = EditorPaths::get_singleton()->get_project_settings_dir().path_join("recent_dirs"); } + + /// File Favorites + Ref<FileAccess> f = FileAccess::open(favorites_file, FileAccess::READ); if (f.is_valid()) { String line = f->get_line().strip_edges(); while (!line.is_empty()) { - favorites.push_back(line); + favorites.append(line); line = f->get_line().strip_edges(); } } + /// Inspector Favorites + + Ref<ConfigFile> cf; + cf.instantiate(); + if (cf->load(favorite_properties_file) == OK) { + List<String> secs; + cf->get_sections(&secs); + + for (String &E : secs) { + PackedStringArray properties = PackedStringArray(cf->get_value(E, "properties")); + if (EditorNode::get_editor_data().is_type_recognized(E) || ResourceLoader::exists(E, "Script")) { + for (const String &property : properties) { + if (!favorite_properties[E].has(property)) { + favorite_properties[E].push_back(property); + } + } + } + } + } + + /// Recent Directories + f = FileAccess::open(recent_dirs_file, FileAccess::READ); if (f.is_valid()) { String line = f->get_line().strip_edges(); diff --git a/editor/editor_settings.h b/editor/editor_settings.h index d1ccedfe6c..3c8a4de866 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -102,6 +102,7 @@ private: HashMap<String, List<Ref<InputEvent>>> builtin_action_overrides; Vector<String> favorites; + HashMap<String, PackedStringArray> favorite_properties; Vector<String> recent_dirs; bool save_changed_setting = true; @@ -176,6 +177,8 @@ public: void set_favorites(const Vector<String> &p_favorites); Vector<String> get_favorites() const; + void set_favorite_properties(const HashMap<String, PackedStringArray> &p_favorite_properties); + HashMap<String, PackedStringArray> get_favorite_properties() const; void set_recent_dirs(const Vector<String> &p_recent_dirs); Vector<String> get_recent_dirs() const; void load_favorites_and_recent_dirs(); diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp index d6742c9b55..8989b9cf9b 100644 --- a/editor/editor_settings_dialog.cpp +++ b/editor/editor_settings_dialog.cpp @@ -106,8 +106,8 @@ void EditorSettingsDialog::update_navigation_preset() { orbit_mod_key_2 = InputEventKey::create_reference(Key::NONE); pan_mod_key_1 = InputEventKey::create_reference(Key::SHIFT); pan_mod_key_2 = InputEventKey::create_reference(Key::NONE); - zoom_mod_key_1 = InputEventKey::create_reference(Key::SHIFT); - zoom_mod_key_2 = InputEventKey::create_reference(Key::CTRL); + zoom_mod_key_1 = InputEventKey::create_reference(Key::CTRL); + zoom_mod_key_2 = InputEventKey::create_reference(Key::NONE); } else if (nav_scheme == Node3DEditorViewport::NAVIGATION_MAYA) { set_preset = true; set_orbit_mouse_button = Node3DEditorViewport::NAVIGATION_LEFT_MOUSE; diff --git a/editor/export/codesign.cpp b/editor/export/codesign.cpp index 72d496b04d..cc53068d48 100644 --- a/editor/export/codesign.cpp +++ b/editor/export/codesign.cpp @@ -1381,14 +1381,14 @@ Error CodeSign::_codesign_file(bool p_use_hardened_runtime, bool p_force, const r_error_msg = TTR("Invalid entitlements file."); ERR_FAIL_V_MSG(FAILED, "CodeSign: Invalid entitlements file."); } - cet = Ref<CodeSignEntitlementsText>(memnew(CodeSignEntitlementsText(entitlements))); - ceb = Ref<CodeSignEntitlementsBinary>(memnew(CodeSignEntitlementsBinary(entitlements))); + cet.instantiate(entitlements); + ceb.instantiate(entitlements); } print_verbose("CodeSign: Generating requirements..."); Ref<CodeSignRequirements> rq; String team_id = ""; - rq = Ref<CodeSignRequirements>(memnew(CodeSignRequirements())); + rq.instantiate(); // Sign executables. for (int i = 0; i < files_to_sign.size(); i++) { @@ -1487,7 +1487,7 @@ Error CodeSign::_codesign_file(bool p_use_hardened_runtime, bool p_force, const print_verbose("CodeSign: Generating signature..."); Ref<CodeSignSignature> cs; - cs = Ref<CodeSignSignature>(memnew(CodeSignSignature())); + cs.instantiate(); print_verbose("CodeSign: Writing signature superblob..."); // Write signature data to the executable. diff --git a/editor/export/editor_export.cpp b/editor/export/editor_export.cpp index 6ca83c5e25..cddc8173cb 100644 --- a/editor/export/editor_export.cpp +++ b/editor/export/editor_export.cpp @@ -87,6 +87,8 @@ void EditorExport::_save() { config->set_value(section, "encryption_include_filters", preset->get_enc_in_filter()); config->set_value(section, "encryption_exclude_filters", preset->get_enc_ex_filter()); + config->set_value(section, "seed", preset->get_seed()); + config->set_value(section, "encrypt_pck", preset->get_enc_pck()); config->set_value(section, "encrypt_directory", preset->get_enc_directory()); config->set_value(section, "script_export_mode", preset->get_script_export_mode()); @@ -307,6 +309,9 @@ void EditorExport::load_config() { preset->set_script_export_mode(config->get_value(section, "script_export_mode", EditorExportPreset::MODE_SCRIPT_BINARY_TOKENS_COMPRESSED)); preset->set_patches(config->get_value(section, "patches", Vector<String>())); + if (config->has_section_key(section, "seed")) { + preset->set_seed(config->get_value(section, "seed")); + } if (config->has_section_key(section, "encrypt_pck")) { preset->set_enc_pck(config->get_value(section, "encrypt_pck")); } diff --git a/editor/export/editor_export_platform.cpp b/editor/export/editor_export_platform.cpp index 50fa49dc52..91c9ff9807 100644 --- a/editor/export/editor_export_platform.cpp +++ b/editor/export/editor_export_platform.cpp @@ -59,6 +59,17 @@ static int _get_pad(int p_alignment, int p_n) { return pad; } +template <typename T> +static bool _has_pack_path(const T &p_paths, const String &p_path) { + for (const String &E : p_paths) { + if (E.simplify_path().trim_prefix("res://") == p_path) { + return true; + } + } + + return false; +} + #define PCK_PADDING 16 bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err) { @@ -205,26 +216,28 @@ void EditorExportPlatform::_unload_patches() { PackedData::get_singleton()->clear(); } -Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { +Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed) { ERR_FAIL_COND_V_MSG(p_total < 1, ERR_PARAMETER_RANGE_ERROR, "Must select at least one file to export."); PackData *pd = (PackData *)p_userdata; + String simplified_path = p_path.simplify_path(); + SavedData sd; - sd.path_utf8 = p_path.utf8(); + sd.path_utf8 = simplified_path.trim_prefix("res://").utf8(); sd.ofs = pd->f->get_position(); sd.size = p_data.size(); sd.encrypted = false; for (int i = 0; i < p_enc_in_filters.size(); ++i) { - if (p_path.matchn(p_enc_in_filters[i]) || p_path.replace("res://", "").matchn(p_enc_in_filters[i])) { + if (simplified_path.matchn(p_enc_in_filters[i]) || simplified_path.trim_prefix("res://").matchn(p_enc_in_filters[i])) { sd.encrypted = true; break; } } for (int i = 0; i < p_enc_ex_filters.size(); ++i) { - if (p_path.matchn(p_enc_ex_filters[i]) || p_path.replace("res://", "").matchn(p_enc_ex_filters[i])) { + if (simplified_path.matchn(p_enc_ex_filters[i]) || simplified_path.trim_prefix("res://").matchn(p_enc_ex_filters[i])) { sd.encrypted = false; break; } @@ -234,10 +247,27 @@ Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_pa Ref<FileAccess> ftmp = pd->f; if (sd.encrypted) { + Vector<uint8_t> iv; + if (p_seed != 0) { + uint64_t seed = p_seed; + + const uint8_t *ptr = p_data.ptr(); + int64_t len = p_data.size(); + for (int64_t i = 0; i < len; i++) { + seed = ((seed << 5) + seed) ^ ptr[i]; + } + + RandomPCG rng = RandomPCG(seed, RandomPCG::DEFAULT_INC); + iv.resize(16); + for (int i = 0; i < 16; i++) { + iv.write[i] = rng.rand() % 256; + } + } + fae.instantiate(); ERR_FAIL_COND_V(fae.is_null(), ERR_SKIP); - Error err = fae->open_and_parse(ftmp, p_key, FileAccessEncrypted::MODE_WRITE_AES256, false); + Error err = fae->open_and_parse(ftmp, p_key, FileAccessEncrypted::MODE_WRITE_AES256, false, iv); ERR_FAIL_COND_V(err != OK, ERR_SKIP); ftmp = fae; } @@ -275,15 +305,15 @@ Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_pa return OK; } -Error EditorExportPlatform::_save_pack_patch_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { +Error EditorExportPlatform::_save_pack_patch_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed) { if (_check_hash(PackedData::get_singleton()->get_file_hash(p_path), p_data)) { return OK; } - return _save_pack_file(p_userdata, p_path, p_data, p_file, p_total, p_enc_in_filters, p_enc_ex_filters, p_key); + return _save_pack_file(p_userdata, p_path, p_data, p_file, p_total, p_enc_in_filters, p_enc_ex_filters, p_key, p_seed); } -Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { +Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed) { ERR_FAIL_COND_V_MSG(p_total < 1, ERR_PARAMETER_RANGE_ERROR, "Must select at least one file to export."); String path = p_path.replace_first("res://", ""); @@ -315,12 +345,12 @@ Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_pat return OK; } -Error EditorExportPlatform::_save_zip_patch_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { +Error EditorExportPlatform::_save_zip_patch_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed) { if (_check_hash(PackedData::get_singleton()->get_file_hash(p_path), p_data)) { return OK; } - return _save_zip_file(p_userdata, p_path, p_data, p_file, p_total, p_enc_in_filters, p_enc_ex_filters, p_key); + return _save_zip_file(p_userdata, p_path, p_data, p_file, p_total, p_enc_in_filters, p_enc_ex_filters, p_key, p_seed); } Ref<ImageTexture> EditorExportPlatform::get_option_icon(int p_index) const { @@ -919,7 +949,7 @@ Vector<String> EditorExportPlatform::get_forced_export_files() { return files; } -Error EditorExportPlatform::_script_save_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { +Error EditorExportPlatform::_script_save_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed) { Callable cb = ((ScriptCallbackData *)p_userdata)->file_cb; ERR_FAIL_COND_V(!cb.is_valid(), FAILED); @@ -965,10 +995,10 @@ Error EditorExportPlatform::_export_project_files(const Ref<EditorExportPreset> ScriptCallbackData data; data.file_cb = p_save_func; data.so_cb = p_so_func; - return export_project_files(p_preset, p_debug, _script_save_file, &data, _script_add_shared_object); + return export_project_files(p_preset, p_debug, _script_save_file, nullptr, &data, _script_add_shared_object); } -Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func) { +Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_save_func, EditorExportRemoveFunction p_remove_func, void *p_udata, EditorExportSaveSharedObject p_so_func) { //figure out paths of files that will be exported HashSet<String> paths; Vector<String> path_remaps; @@ -1030,8 +1060,10 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & Vector<String> enc_in_filters; Vector<String> enc_ex_filters; Vector<uint8_t> key; + uint64_t seed = 0; if (enc_pck) { + seed = p_preset->get_seed(); Vector<String> enc_in_split = p_preset->get_enc_in_filter().split(","); for (int i = 0; i < enc_in_split.size(); i++) { String f = enc_in_split[i].strip_edges(); @@ -1082,6 +1114,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & Error err = OK; Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins(); + Vector<String> extra_paths; struct SortByName { bool operator()(const Ref<EditorExportPlugin> &left, const Ref<EditorExportPlugin> &right) const { @@ -1102,10 +1135,12 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & } } for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) { - err = p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size(), enc_in_filters, enc_ex_filters, key); + err = p_save_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size(), enc_in_filters, enc_ex_filters, key, seed); if (err != OK) { return err; } + + extra_paths.push_back(export_plugins[i]->extra_files[j].path); } export_plugins.write[i]->_clear(); @@ -1218,7 +1253,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & } for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) { - err = p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_save_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total, enc_in_filters, enc_ex_filters, key, seed); if (err != OK) { return err; } @@ -1227,6 +1262,8 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & path_remaps.push_back(path); path_remaps.push_back(export_plugins[i]->extra_files[j].path); } + + extra_paths.push_back(export_plugins[i]->extra_files[j].path); } if (export_plugins[i]->skipped) { @@ -1248,7 +1285,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & if (importer_type == "keep") { // Just keep file as-is. Vector<uint8_t> array = FileAccess::get_file_as_bytes(path); - err = p_func(p_udata, path, array, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_save_func(p_udata, path, array, idx, total, enc_in_filters, enc_ex_filters, key, seed); if (err != OK) { return err; @@ -1291,13 +1328,13 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & sarr.resize(cs.size()); memcpy(sarr.ptrw(), cs.ptr(), sarr.size()); - err = p_func(p_udata, path + ".import", sarr, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_save_func(p_udata, path + ".import", sarr, idx, total, enc_in_filters, enc_ex_filters, key, seed); if (err != OK) { return err; } // Now actual remapped file: sarr = FileAccess::get_file_as_bytes(export_path); - err = p_func(p_udata, export_path, sarr, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_save_func(p_udata, export_path, sarr, idx, total, enc_in_filters, enc_ex_filters, key, seed); if (err != OK) { return err; } @@ -1327,14 +1364,14 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & if (remap == "path") { String remapped_path = config->get_value("remap", remap); Vector<uint8_t> array = FileAccess::get_file_as_bytes(remapped_path); - err = p_func(p_udata, remapped_path, array, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_save_func(p_udata, remapped_path, array, idx, total, enc_in_filters, enc_ex_filters, key, seed); } else if (remap.begins_with("path.")) { String feature = remap.get_slice(".", 1); if (remap_features.has(feature)) { String remapped_path = config->get_value("remap", remap); Vector<uint8_t> array = FileAccess::get_file_as_bytes(remapped_path); - err = p_func(p_udata, remapped_path, array, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_save_func(p_udata, remapped_path, array, idx, total, enc_in_filters, enc_ex_filters, key, seed); } else { // Remove paths if feature not enabled. config->erase_section_key("remap", remap); @@ -1360,7 +1397,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & sarr.resize(cs.size()); memcpy(sarr.ptrw(), cs.ptr(), sarr.size()); - err = p_func(p_udata, path + ".import", sarr, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_save_func(p_udata, path + ".import", sarr, idx, total, enc_in_filters, enc_ex_filters, key, seed); if (err != OK) { return err; @@ -1381,7 +1418,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & } Vector<uint8_t> array = FileAccess::get_file_as_bytes(export_path); - err = p_func(p_udata, export_path, array, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_save_func(p_udata, export_path, array, idx, total, enc_in_filters, enc_ex_filters, key, seed); if (err != OK) { return err; } @@ -1445,7 +1482,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & new_file.write[j] = utf8[j]; } - err = p_func(p_udata, from + ".remap", new_file, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_save_func(p_udata, from + ".remap", new_file, idx, total, enc_in_filters, enc_ex_filters, key, seed); if (err != OK) { return err; } @@ -1459,7 +1496,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & Vector<String> forced_export = get_forced_export_files(); for (int i = 0; i < forced_export.size(); i++) { Vector<uint8_t> array = FileAccess::get_file_as_bytes(forced_export[i]); - err = p_func(p_udata, forced_export[i], array, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_save_func(p_udata, forced_export[i], array, idx, total, enc_in_filters, enc_ex_filters, key, seed); if (err != OK) { return err; } @@ -1471,7 +1508,30 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & Vector<uint8_t> data = FileAccess::get_file_as_bytes(engine_cfb); DirAccess::remove_file_or_error(engine_cfb); - return p_func(p_udata, "res://" + config_file, data, idx, total, enc_in_filters, enc_ex_filters, key); + err = p_save_func(p_udata, "res://" + config_file, data, idx, total, enc_in_filters, enc_ex_filters, key, seed); + if (err != OK) { + return err; + } + + if (p_remove_func) { + for (const String &E : PackedData::get_singleton()->get_file_paths()) { + String simplified_path = E.simplify_path(); + if (simplified_path == config_file) { + continue; + } + + String pack_path = simplified_path.trim_suffix(".remap"); + + if (!_has_pack_path(paths, pack_path) && !_has_pack_path(extra_paths, pack_path) && !_has_pack_path(path_remaps, pack_path) && !_has_pack_path(forced_export, pack_path)) { + err = p_remove_func(p_udata, E); + if (err != OK) { + return err; + } + } + } + } + + return OK; } Error EditorExportPlatform::_pack_add_shared_object(void *p_userdata, const SharedObject &p_so) { @@ -1483,6 +1543,29 @@ Error EditorExportPlatform::_pack_add_shared_object(void *p_userdata, const Shar return OK; } +Error EditorExportPlatform::_remove_pack_file(void *p_userdata, const String &p_path) { + PackData *pd = (PackData *)p_userdata; + + SavedData sd; + sd.path_utf8 = p_path.utf8(); + sd.ofs = pd->f->get_position(); + sd.size = 0; + sd.removal = true; + + // This padding will likely never be added, as we should already be aligned when removals are added. + int pad = _get_pad(PCK_PADDING, pd->f->get_position()); + for (int i = 0; i < pad; i++) { + pd->f->store_8(0); + } + + sd.md5.resize(16); + sd.md5.fill(0); + + pd->file_ofs.push_back(sd); + + return OK; +} + Error EditorExportPlatform::_zip_add_shared_object(void *p_userdata, const SharedObject &p_so) { ZipData *zip_data = (ZipData *)p_userdata; if (zip_data->so_files) { @@ -1613,7 +1696,7 @@ Dictionary EditorExportPlatform::_save_pack(const Ref<EditorExportPreset> &p_pre Vector<SharedObject> so_files; int64_t embedded_start = 0; int64_t embedded_size = 0; - Error err_code = save_pack(p_preset, p_debug, p_path, &so_files, nullptr, p_embed, &embedded_start, &embedded_size); + Error err_code = save_pack(p_preset, p_debug, p_path, &so_files, nullptr, nullptr, p_embed, &embedded_start, &embedded_size); Dictionary ret; ret["result"] = err_code; @@ -1699,7 +1782,7 @@ Dictionary EditorExportPlatform::_save_zip_patch(const Ref<EditorExportPreset> & return ret; } -Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files, EditorExportSaveFunction p_save_func, bool p_embed, int64_t *r_embedded_start, int64_t *r_embedded_size) { +Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files, EditorExportSaveFunction p_save_func, EditorExportRemoveFunction p_remove_func, bool p_embed, int64_t *r_embedded_start, int64_t *r_embedded_size) { EditorProgress ep("savepack", TTR("Packing"), 102, true); if (p_save_func == nullptr) { @@ -1722,7 +1805,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, b pd.f = ftmp; pd.so_files = p_so_files; - Error err = export_project_files(p_preset, p_debug, p_save_func, &pd, _pack_add_shared_object); + Error err = export_project_files(p_preset, p_debug, p_save_func, p_remove_func, &pd, _pack_add_shared_object); // Close temp file. pd.f.unref(); @@ -1808,6 +1891,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, b Ref<FileAccess> fhead = f; if (enc_pck && enc_directory) { + uint64_t seed = p_preset->get_seed(); String script_key = _get_script_encryption_key(p_preset); Vector<uint8_t> key; key.resize(32); @@ -1842,7 +1926,27 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, b return ERR_CANT_CREATE; } - err = fae->open_and_parse(f, key, FileAccessEncrypted::MODE_WRITE_AES256, false); + Vector<uint8_t> iv; + if (seed != 0) { + for (int i = 0; i < pd.file_ofs.size(); i++) { + for (int64_t j = 0; j < pd.file_ofs[i].path_utf8.length(); j++) { + seed = ((seed << 5) + seed) ^ pd.file_ofs[i].path_utf8.get_data()[j]; + } + for (int64_t j = 0; j < pd.file_ofs[i].md5.size(); j++) { + seed = ((seed << 5) + seed) ^ pd.file_ofs[i].md5[j]; + } + seed = ((seed << 5) + seed) ^ pd.file_ofs[i].ofs; + seed = ((seed << 5) + seed) ^ pd.file_ofs[i].size; + } + + RandomPCG rng = RandomPCG(seed, RandomPCG::DEFAULT_INC); + iv.resize(16); + for (int i = 0; i < 16; i++) { + iv.write[i] = rng.rand() % 256; + } + } + + err = fae->open_and_parse(f, key, FileAccessEncrypted::MODE_WRITE_AES256, false, iv); if (err != OK) { add_message(EXPORT_MESSAGE_ERROR, TTR("Save PCK"), TTR("Can't open encrypted file to write.")); return ERR_CANT_CREATE; @@ -1868,6 +1972,9 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, b if (pd.file_ofs[i].encrypted) { flags |= PACK_FILE_ENCRYPTED; } + if (pd.file_ofs[i].removal) { + flags |= PACK_FILE_REMOVAL; + } fhead->store_32(flags); } @@ -1936,7 +2043,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, b } Error EditorExportPlatform::save_pack_patch(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files, bool p_embed, int64_t *r_embedded_start, int64_t *r_embedded_size) { - return save_pack(p_preset, p_debug, p_path, p_so_files, _save_pack_patch_file, p_embed, r_embedded_start, r_embedded_size); + return save_pack(p_preset, p_debug, p_path, p_so_files, _save_pack_patch_file, _remove_pack_file, p_embed, r_embedded_start, r_embedded_size); } Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files, EditorExportSaveFunction p_save_func) { @@ -1957,7 +2064,7 @@ Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, bo zd.zip = zip; zd.so_files = p_so_files; - Error err = export_project_files(p_preset, p_debug, p_save_func, &zd, _zip_add_shared_object); + Error err = export_project_files(p_preset, p_debug, p_save_func, nullptr, &zd, _zip_add_shared_object); if (err != OK && err != ERR_SKIP) { add_message(EXPORT_MESSAGE_ERROR, TTR("Save ZIP"), TTR("Failed to export project files.")); } diff --git a/editor/export/editor_export_platform.h b/editor/export/editor_export_platform.h index ef3274c5e4..c7378ffec7 100644 --- a/editor/export/editor_export_platform.h +++ b/editor/export/editor_export_platform.h @@ -53,7 +53,8 @@ protected: static void _bind_methods(); public: - typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); + typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed); + typedef Error (*EditorExportRemoveFunction)(void *p_userdata, const String &p_path); typedef Error (*EditorExportSaveSharedObject)(void *p_userdata, const SharedObject &p_so); enum DebugFlags { @@ -82,6 +83,7 @@ private: uint64_t ofs = 0; uint64_t size = 0; bool encrypted = false; + bool removal = false; Vector<uint8_t> md5; CharString path_utf8; @@ -112,12 +114,14 @@ private: static bool _check_hash(const uint8_t *p_hash, const Vector<uint8_t> &p_data); - static Error _save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); - static Error _save_pack_patch_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); + static Error _save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed); + static Error _save_pack_patch_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed); static Error _pack_add_shared_object(void *p_userdata, const SharedObject &p_so); - static Error _save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); - static Error _save_zip_patch_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); + static Error _remove_pack_file(void *p_userdata, const String &p_path); + + static Error _save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed); + static Error _save_zip_patch_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed); static Error _zip_add_shared_object(void *p_userdata, const SharedObject &p_so); struct ScriptCallbackData { @@ -125,7 +129,7 @@ private: Callable so_cb; }; - static Error _script_save_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); + static Error _script_save_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed); static Error _script_add_shared_object(void *p_userdata, const SharedObject &p_so); void _edit_files_with_filter(Ref<DirAccess> &da, const Vector<String> &p_filters, HashSet<String> &r_list, bool exclude); @@ -287,7 +291,7 @@ public: Array get_current_presets() const; Error _export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, const Callable &p_save_func, const Callable &p_so_func); - Error export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func = nullptr); + Error export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_save_func, EditorExportRemoveFunction p_remove_func, void *p_udata, EditorExportSaveSharedObject p_so_func = nullptr); Dictionary _save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, bool p_embed = false); Dictionary _save_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path); @@ -295,7 +299,7 @@ public: Dictionary _save_pack_patch(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path); Dictionary _save_zip_patch(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path); - Error save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, EditorExportSaveFunction p_save_func = nullptr, bool p_embed = false, int64_t *r_embedded_start = nullptr, int64_t *r_embedded_size = nullptr); + Error save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, EditorExportSaveFunction p_save_func = nullptr, EditorExportRemoveFunction p_remove_func = nullptr, bool p_embed = false, int64_t *r_embedded_start = nullptr, int64_t *r_embedded_size = nullptr); Error save_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, EditorExportSaveFunction p_save_func = nullptr); Error save_pack_patch(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, bool p_embed = false, int64_t *r_embedded_start = nullptr, int64_t *r_embedded_size = nullptr); diff --git a/editor/export/editor_export_platform_pc.cpp b/editor/export/editor_export_platform_pc.cpp index 52f7a0cee8..4eff096840 100644 --- a/editor/export/editor_export_platform_pc.cpp +++ b/editor/export/editor_export_platform_pc.cpp @@ -194,7 +194,7 @@ Error EditorExportPlatformPC::export_project_data(const Ref<EditorExportPreset> int64_t embedded_pos; int64_t embedded_size; - Error err = save_pack(p_preset, p_debug, pck_path, &so_files, nullptr, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size); + Error err = save_pack(p_preset, p_debug, pck_path, &so_files, nullptr, nullptr, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size); if (err == OK && p_preset->get("binary_format/embed_pck")) { if (embedded_size >= 0x100000000 && String(p_preset->get("binary_format/architecture")).contains("32")) { add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB.")); diff --git a/editor/export/editor_export_preset.cpp b/editor/export/editor_export_preset.cpp index da7059b777..8ff5dd7551 100644 --- a/editor/export/editor_export_preset.cpp +++ b/editor/export/editor_export_preset.cpp @@ -451,6 +451,15 @@ String EditorExportPreset::get_enc_ex_filter() const { return enc_ex_filters; } +void EditorExportPreset::set_seed(uint64_t p_seed) { + seed = p_seed; + EditorExport::singleton->save_presets(); +} + +uint64_t EditorExportPreset::get_seed() const { + return seed; +} + void EditorExportPreset::set_enc_pck(bool p_enabled) { enc_pck = p_enabled; EditorExport::singleton->save_presets(); diff --git a/editor/export/editor_export_preset.h b/editor/export/editor_export_preset.h index af3a23fc50..4834a483eb 100644 --- a/editor/export/editor_export_preset.h +++ b/editor/export/editor_export_preset.h @@ -92,6 +92,7 @@ private: String enc_ex_filters; bool enc_pck = false; bool enc_directory = false; + uint64_t seed = 0; String script_key; int script_mode = MODE_SCRIPT_BINARY_TOKENS_COMPRESSED; @@ -165,6 +166,9 @@ public: void set_enc_ex_filter(const String &p_filter); String get_enc_ex_filter() const; + void set_seed(uint64_t p_seed); + uint64_t get_seed() const; + void set_enc_pck(bool p_enabled); bool get_enc_pck() const; diff --git a/editor/export/project_export.cpp b/editor/export/project_export.cpp index a3cd6523e9..8ae4b856a0 100644 --- a/editor/export/project_export.cpp +++ b/editor/export/project_export.cpp @@ -382,10 +382,16 @@ void ProjectExportDialog::_edit_preset(int p_index) { bool enc_pck_mode = current->get_enc_pck(); enc_pck->set_pressed(enc_pck_mode); + uint64_t seed = current->get_seed(); + if (!updating_seed) { + seed_input->set_text(itos(seed)); + } + enc_directory->set_disabled(!enc_pck_mode); enc_in_filters->set_editable(enc_pck_mode); enc_ex_filters->set_editable(enc_pck_mode); script_key->set_editable(enc_pck_mode); + seed_input->set_editable(enc_pck_mode); bool enc_directory_mode = current->get_enc_directory(); enc_directory->set_pressed(enc_directory_mode); @@ -591,6 +597,21 @@ void ProjectExportDialog::_enc_pck_changed(bool p_pressed) { _update_current_preset(); } +void ProjectExportDialog::_seed_input_changed(const String &p_text) { + if (updating) { + return; + } + + Ref<EditorExportPreset> current = get_current_preset(); + ERR_FAIL_COND(current.is_null()); + + current->set_seed(seed_input->get_text().to_int()); + + updating_seed = true; + _update_current_preset(); + updating_seed = false; +} + void ProjectExportDialog::_enc_directory_changed(bool p_pressed) { if (updating) { return; @@ -1623,6 +1644,10 @@ ProjectExportDialog::ProjectExportDialog() { sec_vb->add_child(script_key_error); sections->add_child(sec_scroll_container); + seed_input = memnew(LineEdit); + seed_input->connect(SceneStringName(text_changed), callable_mp(this, &ProjectExportDialog::_seed_input_changed)); + sec_vb->add_margin_child(TTR("Initialization vector seed"), seed_input); + Label *sec_info = memnew(Label); sec_info->set_text(TTR("Note: Encryption key needs to be stored in the binary,\nyou need to build the export templates from source.")); sec_vb->add_child(sec_info); diff --git a/editor/export/project_export.h b/editor/export/project_export.h index bbf0d81228..68676bfc84 100644 --- a/editor/export/project_export.h +++ b/editor/export/project_export.h @@ -172,6 +172,7 @@ class ProjectExportDialog : public ConfirmationDialog { CheckButton *enc_directory = nullptr; LineEdit *enc_in_filters = nullptr; LineEdit *enc_ex_filters = nullptr; + LineEdit *seed_input = nullptr; OptionButton *script_mode = nullptr; @@ -192,9 +193,11 @@ class ProjectExportDialog : public ConfirmationDialog { bool updating_script_key = false; bool updating_enc_filters = false; + bool updating_seed = false; void _enc_pck_changed(bool p_pressed); void _enc_directory_changed(bool p_pressed); void _enc_filters_changed(const String &p_text); + void _seed_input_changed(const String &p_text); void _script_encryption_key_changed(const String &p_key); bool _validate_script_encryption_key(const String &p_key); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 9b08d21bdc..3921cde71e 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -203,9 +203,7 @@ Ref<Texture2D> FileSystemDock::_get_tree_item_icon(bool p_is_valid, const String } } -bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites, bool p_unfold_path) { - bool parent_should_expand = false; - +void FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites, bool p_unfold_path) { // Create a tree item for the subdirectory. TreeItem *subdirectory_item = tree->create_item(p_parent); String dname = p_dir->get_name(); @@ -213,6 +211,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory if (dname.is_empty()) { dname = "res://"; + resources_item = subdirectory_item; } // Set custom folder color (if applicable). @@ -258,16 +257,13 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory } else { subdirectory_item->set_collapsed(!uncollapsed_paths.has(lpath)); } - if (!searched_tokens.is_empty() && _matches_all_search_tokens(dname)) { - parent_should_expand = true; - } // Create items for all subdirectories. bool reversed = file_sort == FileSortOption::FILE_SORT_NAME_REVERSE; for (int i = reversed ? p_dir->get_subdir_count() - 1 : 0; reversed ? i >= 0 : i < p_dir->get_subdir_count(); reversed ? i-- : i++) { - parent_should_expand = (_create_tree(subdirectory_item, p_dir->get_subdir(i), uncollapsed_paths, p_select_in_favorites, p_unfold_path) || parent_should_expand); + _create_tree(subdirectory_item, p_dir->get_subdir(i), uncollapsed_paths, p_select_in_favorites, p_unfold_path); } // Create all items for the files in the subdirectory. @@ -283,17 +279,6 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory continue; } - String file_name = p_dir->get_file(i); - if (!searched_tokens.is_empty()) { - if (!_matches_all_search_tokens(file_name)) { - // The searched string is not in the file name, we skip it. - continue; - } else { - // We expand all parents. - parent_should_expand = true; - } - } - FileInfo file_info; file_info.name = p_dir->get_file(i); file_info.type = p_dir->get_file_type(i); @@ -346,24 +331,12 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory subdirectory_item->set_as_cursor(0); } } - - if (!searched_tokens.is_empty()) { - if (parent_should_expand) { - subdirectory_item->set_collapsed(false); - } else if (dname != "res://") { - subdirectory_item->get_parent()->remove_child(subdirectory_item); - memdelete(subdirectory_item); - } - } - - return parent_should_expand; } Vector<String> FileSystemDock::get_uncollapsed_paths() const { Vector<String> uncollapsed_paths; TreeItem *root = tree->get_root(); if (root) { - TreeItem *favorites_item = root->get_first_child(); if (!favorites_item->is_collapsed()) { uncollapsed_paths.push_back(favorites_item->get_metadata(0)); } @@ -400,7 +373,7 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo TreeItem *root = tree->create_item(); // Handles the favorites. - TreeItem *favorites_item = tree->create_item(root); + favorites_item = tree->create_item(root); favorites_item->set_icon(0, get_editor_theme_icon(SNAME("Favorites"))); favorites_item->set_text(0, TTR("Favorites:")); favorites_item->set_metadata(0, "Favorites"); @@ -453,24 +426,22 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo color = Color(1, 1, 1); } - if (searched_tokens.is_empty() || _matches_all_search_tokens(text)) { - TreeItem *ti = tree->create_item(favorites_item); - ti->set_text(0, text); - ti->set_icon(0, icon); - ti->set_icon_modulate(0, color); - ti->set_tooltip_text(0, favorite); - ti->set_selectable(0, true); - ti->set_metadata(0, favorite); - if (p_select_in_favorites && favorite == current_path) { - ti->select(0); - ti->set_as_cursor(0); - } - if (!favorite.ends_with("/")) { - Array udata; - udata.push_back(tree_update_id); - udata.push_back(ti); - EditorResourcePreview::get_singleton()->queue_resource_preview(favorite, this, "_tree_thumbnail_done", udata); - } + TreeItem *ti = tree->create_item(favorites_item); + ti->set_text(0, text); + ti->set_icon(0, icon); + ti->set_icon_modulate(0, color); + ti->set_tooltip_text(0, favorite); + ti->set_selectable(0, true); + ti->set_metadata(0, favorite); + if (p_select_in_favorites && favorite == current_path) { + ti->select(0); + ti->set_as_cursor(0); + } + if (!favorite.ends_with("/")) { + Array udata; + udata.push_back(tree_update_id); + udata.push_back(ti); + EditorResourcePreview::get_singleton()->queue_resource_preview(favorite, this, "_tree_thumbnail_done", udata); } } @@ -676,7 +647,6 @@ void FileSystemDock::_tree_multi_selected(Object *p_item, int p_column, bool p_s return; } - TreeItem *favorites_item = tree->get_root()->get_first_child(); if (selected->get_parent() == favorites_item && !String(selected->get_metadata(0)).ends_with("/")) { // Go to the favorites if we click in the favorites and the path has changed. current_path = "Favorites"; @@ -771,6 +741,36 @@ void FileSystemDock::_navigate_to_path(const String &p_path, bool p_select_in_fa } } +bool FileSystemDock::_update_filtered_items(TreeItem *p_tree_item) { + TreeItem *item = p_tree_item; + if (!item) { + item = tree->get_root(); + } + ERR_FAIL_NULL_V(item, false); + + bool keep_visible = false; + for (TreeItem *child = item->get_first_child(); child; child = child->get_next()) { + keep_visible = _update_filtered_items(child) || keep_visible; + } + + if (searched_tokens.is_empty()) { + item->set_visible(true); + // Always uncollapse root (the hidden item above res:// and favorites). + item->set_collapsed(item != tree->get_root() && !uncollapsed_paths_before_search.has(item->get_metadata(0))); + return true; + } + + if (keep_visible) { + item->set_collapsed(false); + } else { + // res:// and favorites are always visible. + keep_visible = item == resources_item || item == favorites_item; + keep_visible = keep_visible || _matches_all_search_tokens(item->get_text(0)); + } + item->set_visible(keep_visible); + return keep_visible; +} + void FileSystemDock::navigate_to_path(const String &p_path) { file_list_search_box->clear(); _navigate_to_path(p_path); @@ -1446,6 +1446,13 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ } } + if (p_item.is_file && FileAccess::exists(old_path + ".uid")) { + err = da->rename(old_path + ".uid", new_path + ".uid"); + if (err != OK) { + EditorNode::get_singleton()->add_io_error(TTR("Error moving:") + "\n" + old_path + ".uid\n"); + } + } + // Update scene if it is open. for (int i = 0; i < file_changed_paths.size(); ++i) { String new_item_path = p_item.is_file ? new_path : file_changed_paths[i].replace_first(old_path, new_path); @@ -1641,21 +1648,27 @@ String FileSystemDock::_get_unique_name(const FileOrFolder &p_entry, const Strin return new_path; } -void FileSystemDock::_update_favorites_list_after_move(const HashMap<String, String> &p_files_renames, const HashMap<String, String> &p_folders_renames) const { - Vector<String> favorites_list = EditorSettings::get_singleton()->get_favorites(); - Vector<String> new_favorites; - - for (const String &old_path : favorites_list) { +void FileSystemDock::_update_favorites_after_move(const HashMap<String, String> &p_files_renames, const HashMap<String, String> &p_folders_renames) const { + Vector<String> favorite_files = EditorSettings::get_singleton()->get_favorites(); + Vector<String> new_favorite_files; + for (const String &old_path : favorite_files) { if (p_folders_renames.has(old_path)) { - new_favorites.push_back(p_folders_renames[old_path]); + new_favorite_files.push_back(p_folders_renames[old_path]); } else if (p_files_renames.has(old_path)) { - new_favorites.push_back(p_files_renames[old_path]); + new_favorite_files.push_back(p_files_renames[old_path]); } else { - new_favorites.push_back(old_path); + new_favorite_files.push_back(old_path); } } + EditorSettings::get_singleton()->set_favorites(new_favorite_files); - EditorSettings::get_singleton()->set_favorites(new_favorites); + HashMap<String, PackedStringArray> favorite_properties = EditorSettings::get_singleton()->get_favorite_properties(); + for (const KeyValue<String, String> &KV : p_files_renames) { + if (favorite_properties.has(KV.key)) { + favorite_properties.replace_key(KV.key, KV.value); + } + } + EditorSettings::get_singleton()->set_favorite_properties(favorite_properties); } void FileSystemDock::_make_scene_confirm() { @@ -1798,7 +1811,7 @@ void FileSystemDock::_rename_operation_confirm() { _update_resource_paths_after_move(file_renames, uids); _update_dependencies_after_move(file_renames, file_owners); _update_project_settings_after_move(file_renames, folder_renames); - _update_favorites_list_after_move(file_renames, folder_renames); + _update_favorites_after_move(file_renames, folder_renames); EditorSceneTabs::get_singleton()->set_current_tab(current_tab); @@ -1959,7 +1972,7 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool p_cop _update_resource_paths_after_move(file_renames, uids); _update_dependencies_after_move(file_renames, file_owners); _update_project_settings_after_move(file_renames, folder_renames); - _update_favorites_list_after_move(file_renames, folder_renames); + _update_favorites_after_move(file_renames, folder_renames); EditorSceneTabs::get_singleton()->set_current_tab(current_tab); @@ -2015,7 +2028,6 @@ Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion, bo // Build a list of selected items with the active one at the first position. Vector<String> selected_strings; - TreeItem *favorites_item = tree->get_root()->get_first_child(); TreeItem *cursor_item = tree->get_selected(); if (cursor_item && (p_include_unselected_cursor || cursor_item->is_selected(0)) && cursor_item != favorites_item) { selected_strings.push_back(cursor_item->get_metadata(0)); @@ -2624,16 +2636,12 @@ void FileSystemDock::_search_changed(const String &p_text, const Control *p_from tree_search_box->set_text(searched_string); } - bool unfold_path = (p_text.is_empty() && !current_path.is_empty()); - switch (display_mode) { - case DISPLAY_MODE_TREE_ONLY: { - _update_tree(searched_tokens.is_empty() ? uncollapsed_paths_before_search : Vector<String>(), false, false, unfold_path); - } break; - case DISPLAY_MODE_HSPLIT: - case DISPLAY_MODE_VSPLIT: { - _update_file_list(false); - _update_tree(searched_tokens.is_empty() ? uncollapsed_paths_before_search : Vector<String>(), false, false, unfold_path); - } break; + _update_filtered_items(); + if (display_mode == DISPLAY_MODE_HSPLIT || display_mode == DISPLAY_MODE_VSPLIT) { + _update_file_list(false); + } + if (searched_tokens.is_empty()) { + _navigate_to_path(current_path); } } @@ -2773,7 +2781,6 @@ Variant FileSystemDock::get_drag_data_fw(const Point2 &p_point, Control *p_from) // Check if the first selected is in favorite. TreeItem *selected = tree->get_next_selected(tree->get_root()); while (selected) { - TreeItem *favorites_item = tree->get_root()->get_first_child(); if (selected == favorites_item) { // The "Favorites" item is not draggable. return Variant(); @@ -2825,10 +2832,6 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da } int drop_section = tree->get_drop_section_at_position(p_point); - TreeItem *favorites_item = tree->get_root()->get_first_child(); - - TreeItem *resources_item = favorites_item->get_next(); - if (ti == favorites_item) { return (drop_section == 1); // The parent, first fav. } @@ -2909,9 +2912,6 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, int drop_position; Vector<String> drag_files = drag_data["files"]; - TreeItem *favorites_item = tree->get_root()->get_first_child(); - TreeItem *resources_item = favorites_item->get_next(); - if (ti == favorites_item) { // Drop on the favorite folder. drop_position = 0; @@ -3339,7 +3339,6 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, const Vect [[maybe_unused]] bool added_separator = false; if (favorites_list.has(fpath)) { - TreeItem *favorites_item = tree->get_root()->get_first_child(); TreeItem *cursor_item = tree->get_selected(); bool is_item_in_favorites = false; while (cursor_item != nullptr) { diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 72d5ac3a98..d2e403a8af 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -232,6 +232,8 @@ private: FileSystemTree *tree = nullptr; FileSystemList *files = nullptr; bool import_dock_needs_update = false; + TreeItem *resources_item = nullptr; + TreeItem *favorites_item = nullptr; bool holding_branch = false; Vector<TreeItem *> tree_items_selected_on_drag_begin; @@ -245,9 +247,10 @@ private: void _reselect_items_selected_on_drag_begin(bool reset = false); Ref<Texture2D> _get_tree_item_icon(bool p_is_valid, const String &p_file_type, const String &p_icon_path); - bool _create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites, bool p_unfold_path = false); + void _create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites, bool p_unfold_path = false); void _update_tree(const Vector<String> &p_uncollapsed_paths = Vector<String>(), bool p_uncollapse_root = false, bool p_select_in_favorites = false, bool p_unfold_path = false); void _navigate_to_path(const String &p_path, bool p_select_in_favorites = false); + bool _update_filtered_items(TreeItem *p_tree_item = nullptr); void _file_list_gui_input(Ref<InputEvent> p_event); void _tree_gui_input(Ref<InputEvent> p_event); @@ -275,7 +278,7 @@ private: void _before_move(HashMap<String, ResourceUID::ID> &r_uids, HashSet<String> &r_file_owners) const; void _update_dependencies_after_move(const HashMap<String, String> &p_renames, const HashSet<String> &p_file_owners) const; void _update_resource_paths_after_move(const HashMap<String, String> &p_renames, const HashMap<String, ResourceUID::ID> &p_uids) const; - void _update_favorites_list_after_move(const HashMap<String, String> &p_files_renames, const HashMap<String, String> &p_folders_renames) const; + void _update_favorites_after_move(const HashMap<String, String> &p_files_renames, const HashMap<String, String> &p_folders_renames) const; void _update_project_settings_after_move(const HashMap<String, String> &p_renames, const HashMap<String, String> &p_folders_renames); String _get_unique_name(const FileOrFolder &p_entry, const String &p_at_path); diff --git a/editor/gui/editor_bottom_panel.cpp b/editor/gui/editor_bottom_panel.cpp index 2eb899f085..3cc1e37be0 100644 --- a/editor/gui/editor_bottom_panel.cpp +++ b/editor/gui/editor_bottom_panel.cpp @@ -31,35 +31,35 @@ #include "editor_bottom_panel.h" #include "editor/debugger/editor_debugger_node.h" -#include "editor/editor_about.h" #include "editor/editor_command_palette.h" #include "editor/editor_node.h" #include "editor/editor_string_names.h" -#include "editor/engine_update_label.h" #include "editor/gui/editor_toaster.h" #include "editor/gui/editor_version_button.h" #include "editor/themes/editor_scale.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" +#include "scene/gui/split_container.h" void EditorBottomPanel::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: { + pin_button->set_button_icon(get_editor_theme_icon(SNAME("Pin"))); expand_button->set_button_icon(get_editor_theme_icon(SNAME("ExpandBottomDock"))); } break; } } -void EditorBottomPanel::_switch_by_control(bool p_visible, Control *p_control) { +void EditorBottomPanel::_switch_by_control(bool p_visible, Control *p_control, bool p_ignore_lock) { for (int i = 0; i < items.size(); i++) { if (items[i].control == p_control) { - _switch_to_item(p_visible, i); + _switch_to_item(p_visible, i, p_ignore_lock); return; } } } -void EditorBottomPanel::_switch_to_item(bool p_visible, int p_idx) { +void EditorBottomPanel::_switch_to_item(bool p_visible, int p_idx, bool p_ignore_lock) { ERR_FAIL_INDEX(p_idx, items.size()); if (items[p_idx].control->is_visible() == p_visible) { @@ -70,6 +70,10 @@ void EditorBottomPanel::_switch_to_item(bool p_visible, int p_idx) { ERR_FAIL_NULL(center_split); if (p_visible) { + if (!p_ignore_lock && lock_panel_switching && pin_button->is_visible()) { + return; + } + for (int i = 0; i < items.size(); i++) { items[i].button->set_pressed_no_signal(i == p_idx); items[i].control->set_visible(i == p_idx); @@ -80,18 +84,23 @@ void EditorBottomPanel::_switch_to_item(bool p_visible, int p_idx) { } else { add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))); } + center_split->set_dragger_visibility(SplitContainer::DRAGGER_VISIBLE); center_split->set_collapsed(false); + pin_button->show(); + + expand_button->show(); if (expand_button->is_pressed()) { EditorNode::get_top_split()->hide(); } - expand_button->show(); } else { add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles))); items[p_idx].button->set_pressed_no_signal(false); items[p_idx].control->set_visible(false); center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN); center_split->set_collapsed(true); + pin_button->hide(); + expand_button->hide(); if (expand_button->is_pressed()) { EditorNode::get_top_split()->show(); @@ -101,13 +110,17 @@ void EditorBottomPanel::_switch_to_item(bool p_visible, int p_idx) { last_opened_control = items[p_idx].control; } +void EditorBottomPanel::_pin_button_toggled(bool p_pressed) { + lock_panel_switching = p_pressed; +} + void EditorBottomPanel::_expand_button_toggled(bool p_pressed) { EditorNode::get_top_split()->set_visible(!p_pressed); } bool EditorBottomPanel::_button_drag_hover(const Vector2 &, const Variant &, Button *p_button, Control *p_control) { if (!p_button->is_pressed()) { - _switch_by_control(true, p_control); + _switch_by_control(true, p_control, true); } return false; } @@ -149,7 +162,7 @@ void EditorBottomPanel::load_layout_from_config(Ref<ConfigFile> p_config_file, c Button *EditorBottomPanel::add_item(String p_text, Control *p_item, const Ref<Shortcut> &p_shortcut, bool p_at_front) { Button *tb = memnew(Button); tb->set_theme_type_variation("BottomPanelButton"); - tb->connect(SceneStringName(toggled), callable_mp(this, &EditorBottomPanel::_switch_by_control).bind(p_item)); + tb->connect(SceneStringName(toggled), callable_mp(this, &EditorBottomPanel::_switch_by_control).bind(p_item, true)); tb->set_drag_forwarding(Callable(), callable_mp(this, &EditorBottomPanel::_button_drag_hover).bind(tb, p_item), Callable()); tb->set_text(p_text); tb->set_shortcut(p_shortcut); @@ -231,10 +244,10 @@ void EditorBottomPanel::toggle_last_opened_bottom_panel() { // Select by control instead of index, so that the last bottom panel is opened correctly // if it's been reordered since. if (last_opened_control) { - _switch_by_control(!last_opened_control->is_visible(), last_opened_control); + _switch_by_control(!last_opened_control->is_visible(), last_opened_control, true); } else { // Open the first panel in the list if no panel was opened this session. - _switch_to_item(true, 0); + _switch_to_item(true, 0, true); } } @@ -263,10 +276,17 @@ EditorBottomPanel::EditorBottomPanel() { Control *h_spacer = memnew(Control); bottom_hbox->add_child(h_spacer); + pin_button = memnew(Button); + bottom_hbox->add_child(pin_button); + pin_button->hide(); + pin_button->set_theme_type_variation("FlatMenuButton"); + pin_button->set_toggle_mode(true); + pin_button->set_tooltip_text(TTR("Pin Bottom Panel Switching")); + pin_button->connect(SceneStringName(toggled), callable_mp(this, &EditorBottomPanel::_pin_button_toggled)); + expand_button = memnew(Button); bottom_hbox->add_child(expand_button); expand_button->hide(); - expand_button->set_flat(false); expand_button->set_theme_type_variation("FlatMenuButton"); expand_button->set_toggle_mode(true); expand_button->set_shortcut(ED_SHORTCUT_AND_COMMAND("editor/bottom_panel_expand", TTR("Expand Bottom Panel"), KeyModifierMask::SHIFT | Key::F12)); diff --git a/editor/gui/editor_bottom_panel.h b/editor/gui/editor_bottom_panel.h index 3d44b3750a..950f0e2570 100644 --- a/editor/gui/editor_bottom_panel.h +++ b/editor/gui/editor_bottom_panel.h @@ -49,16 +49,19 @@ class EditorBottomPanel : public PanelContainer { }; Vector<BottomPanelItem> items; + bool lock_panel_switching = false; VBoxContainer *item_vbox = nullptr; HBoxContainer *bottom_hbox = nullptr; HBoxContainer *button_hbox = nullptr; EditorToaster *editor_toaster = nullptr; + Button *pin_button = nullptr; Button *expand_button = nullptr; Control *last_opened_control = nullptr; - void _switch_by_control(bool p_visible, Control *p_control); - void _switch_to_item(bool p_visible, int p_idx); + void _switch_by_control(bool p_visible, Control *p_control, bool p_ignore_lock = false); + void _switch_to_item(bool p_visible, int p_idx, bool p_ignore_lock = false); + void _pin_button_toggled(bool p_pressed); void _expand_button_toggled(bool p_pressed); bool _button_drag_hover(const Vector2 &, const Variant &, Button *p_button, Control *p_control); diff --git a/editor/gui/editor_spin_slider.cpp b/editor/gui/editor_spin_slider.cpp index 27b6bbafb7..712e91faca 100644 --- a/editor/gui/editor_spin_slider.cpp +++ b/editor/gui/editor_spin_slider.cpp @@ -437,7 +437,7 @@ void EditorSpinSlider::_draw_spin_slider() { Vector2 scale = get_global_transform_with_canvas().get_scale(); grabber->set_scale(scale); grabber->reset_size(); - grabber->set_position(get_global_position() + (grabber_rect.get_center() - grabber->get_size() * 0.5) * scale); + grabber->set_position((grabber_rect.get_center() - grabber->get_size() * 0.5) * scale); if (mousewheel_over_grabber) { Input::get_singleton()->warp_mouse(grabber->get_position() + grabber_rect.size); @@ -731,7 +731,7 @@ EditorSpinSlider::EditorSpinSlider() { grabber = memnew(TextureRect); add_child(grabber); grabber->hide(); - grabber->set_as_top_level(true); + grabber->set_z_index(1); grabber->set_mouse_filter(MOUSE_FILTER_STOP); grabber->connect(SceneStringName(mouse_entered), callable_mp(this, &EditorSpinSlider::_grabber_mouse_entered)); grabber->connect(SceneStringName(mouse_exited), callable_mp(this, &EditorSpinSlider::_grabber_mouse_exited)); diff --git a/editor/gui/editor_toaster.cpp b/editor/gui/editor_toaster.cpp index 4ebd1922a7..ff425ba65e 100644 --- a/editor/gui/editor_toaster.cpp +++ b/editor/gui/editor_toaster.cpp @@ -375,7 +375,7 @@ Control *EditorToaster::popup(Control *p_control, Severity p_severity, double p_ if (p_time > 0.0) { Button *close_button = memnew(Button); close_button->set_flat(true); - close_button->connect(SceneStringName(pressed), callable_mp(this, &EditorToaster::close).bind(panel)); + close_button->connect(SceneStringName(pressed), callable_mp(this, &EditorToaster::instant_close).bind(panel)); hbox_container->add_child(close_button); toast.close_button = close_button; @@ -501,6 +501,19 @@ void EditorToaster::close(Control *p_control) { toasts[p_control].popped = false; } +void EditorToaster::instant_close(Control *p_control) { + close(p_control); + p_control->set_modulate(Color(1, 1, 1, 0)); +} + +void EditorToaster::_bind_methods() { + ClassDB::bind_method(D_METHOD("push_toast", "message", "severity", "tooltip"), &EditorToaster::_popup_str, DEFVAL(EditorToaster::SEVERITY_INFO), DEFVAL(String())); + + BIND_ENUM_CONSTANT(SEVERITY_INFO); + BIND_ENUM_CONSTANT(SEVERITY_WARNING); + BIND_ENUM_CONSTANT(SEVERITY_ERROR); +} + EditorToaster *EditorToaster::get_singleton() { return singleton; } diff --git a/editor/gui/editor_toaster.h b/editor/gui/editor_toaster.h index 35a4337746..0d0080945e 100644 --- a/editor/gui/editor_toaster.h +++ b/editor/gui/editor_toaster.h @@ -105,6 +105,7 @@ private: void _toast_theme_changed(Control *p_control); protected: + static void _bind_methods(); static EditorToaster *singleton; void _notification(int p_what); @@ -115,6 +116,7 @@ public: Control *popup(Control *p_control, Severity p_severity = SEVERITY_INFO, double p_time = 0.0, const String &p_tooltip = String()); void popup_str(const String &p_message, Severity p_severity = SEVERITY_INFO, const String &p_tooltip = String()); void close(Control *p_control); + void instant_close(Control *p_control); EditorToaster(); ~EditorToaster(); diff --git a/editor/gui/scene_tree_editor.cpp b/editor/gui/scene_tree_editor.cpp index 0ada9aa8b2..e89912d5bc 100644 --- a/editor/gui/scene_tree_editor.cpp +++ b/editor/gui/scene_tree_editor.cpp @@ -369,16 +369,14 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { msg_temp += String::utf8("• ") + String(E.name) + "\n"; } } - } - if (num_connections >= 1 || num_groups >= 1) { - if (num_groups < 1) { - msg_temp += "\n"; - } - msg_temp += TTR("Click to show signals dock."); + } else { + msg_temp += "\n"; } Ref<Texture2D> icon_temp; SceneTreeEditorButton signal_temp = BUTTON_SIGNALS; + String msg_temp_end = TTR("Click to show signals dock."); + if (num_connections >= 1 && num_groups >= 1) { icon_temp = get_editor_theme_icon(SNAME("SignalsAndGroups")); } else if (num_connections >= 1) { @@ -386,9 +384,11 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { } else if (num_groups >= 1) { icon_temp = get_editor_theme_icon(SNAME("Groups")); signal_temp = BUTTON_GROUPS; + msg_temp_end = TTR("Click to show groups dock."); } if (num_connections >= 1 || num_groups >= 1) { + msg_temp += msg_temp_end; item->add_button(0, icon_temp, signal_temp, false, msg_temp); } } @@ -1098,8 +1098,19 @@ void SceneTreeEditor::rename_node(Node *p_node, const String &p_name, TreeItem * // Trim leading/trailing whitespace to prevent node names from containing accidental whitespace, which would make it more difficult to get the node via `get_node()`. new_name = new_name.strip_edges(); + if (new_name.is_empty() && p_node->get_owner() != nullptr && !p_node->get_scene_file_path().is_empty()) { + // If name is empty and node is root of an instance, revert to the original name. + const Ref<PackedScene> node_scene = ResourceLoader::load(p_node->get_scene_file_path()); + if (node_scene.is_valid()) { + const Ref<SceneState> &state = node_scene->get_state(); + if (state->get_node_count() > 0) { + new_name = state->get_node_name(0); // Root's name. + } + } + } + if (new_name.is_empty()) { - // If name is empty, fallback to class name. + // If name is still empty, fallback to class name. if (GLOBAL_GET("editor/naming/node_name_casing").operator int() != NAME_CASING_PASCAL_CASE) { new_name = Node::adjust_name_casing(p_node->get_class()); } else { diff --git a/editor/icons/FPS.svg b/editor/icons/FPS.svg new file mode 100644 index 0000000000..5ee818c308 --- /dev/null +++ b/editor/icons/FPS.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#e0e0e0" d="M7.25 4h-2v8h2v-2c1.656 0 3-1.344 3-3 0-1.657-1.344-3-3-3zm0 4v-2c.553 0 1 .448 1 1s-.447 1-1 1zM.25 7v5h2v-2h2v-2h-2v-1c0-.553.447-1 1-1h1v-2h-1c-1.656 0-3 1.344-3 3zM13.25 7c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h2v-2h-2c-1.381 0-2.5 1.119-2.5 2.5s1.119 2.5 2.5 2.5c.276 0 .5.224.5.5s-.224.5-.5.5h-2v2h2c1.381 0 2.5-1.119 2.5-2.5s-1.119-2.5-2.5-2.5z"/></svg>
\ No newline at end of file diff --git a/editor/icons/FlipWinding.svg b/editor/icons/FlipWinding.svg new file mode 100644 index 0000000000..8964ca8d5d --- /dev/null +++ b/editor/icons/FlipWinding.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><rect width="4.596" height="4.596" x="5.7" y="5.7" fill="#e0e0e0" fill-opacity=".6" rx="1" ry="1" transform="rotate(45 8 8)"/><path fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 2a6 6 0 00-2.5 11m.5-3L6 14H2M9 14a6 6 0 002.5-11M11 6 10 2h4"/></svg>
\ No newline at end of file diff --git a/editor/icons/LookAtModifier3D.svg b/editor/icons/LookAtModifier3D.svg new file mode 100644 index 0000000000..9315b297ef --- /dev/null +++ b/editor/icons/LookAtModifier3D.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><g fill="#fc7f7f"><path d="m5.742 11.508c.916-2.959 3.507-4.508 5.592-4.508.803 0 1.673.223 2.492.658.297-.182.563-.423.768-.731.754-1.134.446-2.665-.688-3.419-.309-.205-.66-.338-1.026-.389-.188-1.349-1.433-2.291-2.782-2.103s-2.29 1.433-2.103 2.782c.051.367.184.717.389 1.026l-3.56 3.56c-1.134-.754-2.665-.446-3.419.688s-.446 2.664.688 3.419c.308.205.659.338 1.026.389.188 1.349 1.433 2.29 2.782 2.103.342-.048.658-.164.936-.333-.467-.612-.856-1.337-1.102-2.206-.085-.3-.085-.617.007-.936z"/><path d="m11.334 8c-1.704 0-3.861 1.299-4.637 3.804-.034.119-.034.246 0 .366.745 2.638 2.97 3.83 4.637 3.83s3.891-1.192 4.641-3.816c.034-.12.034-.247 0-.367-.734-2.526-2.938-3.817-4.641-3.817zm0 6.667c-1.473 0-2.667-1.194-2.667-2.667s1.194-2.666 2.667-2.666 2.667 1.193 2.667 2.666-1.194 2.667-2.667 2.667z"/><circle cx="11.334" cy="12" r="1.333"/></g></svg>
\ No newline at end of file diff --git a/editor/icons/Unfavorite.svg b/editor/icons/Unfavorite.svg new file mode 100644 index 0000000000..78f1b90fd0 --- /dev/null +++ b/editor/icons/Unfavorite.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#e0e0e0" d="M 8 1.6992188 L 5.6269531 5.796875 L 1 6.8945312 L 4.2363281 10.302734 L 3.8769531 14.976562 L 8.0175781 12.998047 L 12.173828 14.941406 L 11.777344 10.287109 L 15 6.8945312 L 10.373047 5.796875 L 8 1.6992188 z M 8 4.2773438 L 9.4882812 6.8457031 L 12.388672 7.5332031 L 10.369141 9.6601562 L 10.617188 12.576172 L 8.0097656 11.359375 L 5.4160156 12.599609 L 5.640625 9.6699219 L 3.6113281 7.5332031 L 6.5117188 6.8457031 L 8 4.2773438 z"/></svg>
\ No newline at end of file diff --git a/editor/import/3d/editor_import_collada.cpp b/editor/import/3d/editor_import_collada.cpp index 04a3f23154..c04278fc55 100644 --- a/editor/import/3d/editor_import_collada.cpp +++ b/editor/import/3d/editor_import_collada.cpp @@ -1263,7 +1263,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres //bleh, must ignore invalid ERR_FAIL_COND_V(!collada.state.mesh_data_map.has(meshid), ERR_INVALID_DATA); - mesh = Ref<ImporterMesh>(memnew(ImporterMesh)); + mesh.instantiate(); const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid]; String name = meshdata.name; if (name.is_empty()) { diff --git a/editor/import/3d/resource_importer_obj.cpp b/editor/import/3d/resource_importer_obj.cpp index 3669844207..59d39152e9 100644 --- a/editor/import/3d/resource_importer_obj.cpp +++ b/editor/import/3d/resource_importer_obj.cpp @@ -646,7 +646,7 @@ bool ResourceImporterOBJ::get_option_visibility(const String &p_path, const Stri return true; } -Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterOBJ::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { List<Ref<ImporterMesh>> meshes; Vector<uint8_t> src_lightmap_cache; diff --git a/editor/import/3d/resource_importer_obj.h b/editor/import/3d/resource_importer_obj.h index 9d299bc31a..c4a99428ef 100644 --- a/editor/import/3d/resource_importer_obj.h +++ b/editor/import/3d/resource_importer_obj.h @@ -61,7 +61,7 @@ public: virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override; virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; ResourceImporterOBJ(); }; diff --git a/editor/import/3d/resource_importer_scene.cpp b/editor/import/3d/resource_importer_scene.cpp index edf7aa66f0..86af9caf26 100644 --- a/editor/import/3d/resource_importer_scene.cpp +++ b/editor/import/3d/resource_importer_scene.cpp @@ -2872,7 +2872,7 @@ Error ResourceImporterScene::_check_resource_save_paths(const Dictionary &p_data return OK; } -Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterScene::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { const String &src_path = p_source_file; Ref<EditorSceneFormatImporter> importer; @@ -3092,7 +3092,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p if (!scr.is_valid()) { EditorNode::add_io_error(TTR("Couldn't load post-import script:") + " " + post_import_script_path); } else { - post_import_script = Ref<EditorScenePostImport>(memnew(EditorScenePostImport)); + post_import_script.instantiate(); post_import_script->set_script(scr); if (!post_import_script->get_script_instance()) { EditorNode::add_io_error(TTR("Invalid/broken script for post-import (check console):") + " " + post_import_script_path); diff --git a/editor/import/3d/resource_importer_scene.h b/editor/import/3d/resource_importer_scene.h index daeab2ae03..b2f5fab0eb 100644 --- a/editor/import/3d/resource_importer_scene.h +++ b/editor/import/3d/resource_importer_scene.h @@ -299,7 +299,7 @@ public: void _compress_animations(AnimationPlayer *anim, int p_page_size_kb); Node *pre_import(const String &p_source_file, const HashMap<StringName, Variant> &p_options); - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; virtual bool has_advanced_options() const override; virtual void show_advanced_options(const String &p_path) override; diff --git a/editor/import/audio_stream_import_settings.cpp b/editor/import/audio_stream_import_settings.cpp index 0367e5e3f3..dd45806385 100644 --- a/editor/import/audio_stream_import_settings.cpp +++ b/editor/import/audio_stream_import_settings.cpp @@ -580,12 +580,10 @@ AudioStreamImportSettingsDialog::AudioStreamImportSettingsDialog() { bar_beats_edit->set_max(32); bar_beats_edit->connect(SceneStringName(value_changed), callable_mp(this, &AudioStreamImportSettingsDialog::_settings_changed).unbind(1)); interactive_hb->add_child(bar_beats_edit); - interactive_hb->add_spacer(); main_vbox->add_margin_child(TTR("Music Playback:"), interactive_hb); color_rect = memnew(ColorRect); - main_vbox->add_margin_child(TTR("Preview:"), color_rect); - + main_vbox->add_margin_child(TTR("Preview:"), color_rect, true); color_rect->set_custom_minimum_size(Size2(600, 200) * EDSCALE); color_rect->set_v_size_flags(Control::SIZE_EXPAND_FILL); diff --git a/editor/import/editor_import_plugin.cpp b/editor/import/editor_import_plugin.cpp index 3243dcf256..650c0e27ca 100644 --- a/editor/import/editor_import_plugin.cpp +++ b/editor/import/editor_import_plugin.cpp @@ -163,7 +163,7 @@ bool EditorImportPlugin::get_option_visibility(const String &p_path, const Strin ERR_FAIL_V_MSG(false, "Unimplemented _get_option_visibility in add-on."); } -Error EditorImportPlugin::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error EditorImportPlugin::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { Dictionary options; TypedArray<String> platform_variants, gen_files; diff --git a/editor/import/editor_import_plugin.h b/editor/import/editor_import_plugin.h index ea5cfc2682..df472b416b 100644 --- a/editor/import/editor_import_plugin.h +++ b/editor/import/editor_import_plugin.h @@ -69,7 +69,7 @@ public: virtual int get_import_order() const override; virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const override; virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata = nullptr) override; virtual bool can_import_threaded() const override; Error append_import_external_resource(const String &p_file, const HashMap<StringName, Variant> &p_custom_options = HashMap<StringName, Variant>(), const String &p_custom_importer = String(), Variant p_generator_parameters = Variant()); }; diff --git a/editor/import/resource_importer_bitmask.cpp b/editor/import/resource_importer_bitmask.cpp index e7b7850b02..8441a49666 100644 --- a/editor/import/resource_importer_bitmask.cpp +++ b/editor/import/resource_importer_bitmask.cpp @@ -72,7 +72,7 @@ void ResourceImporterBitMap::get_import_options(const String &p_path, List<Impor r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.5)); } -Error ResourceImporterBitMap::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterBitMap::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { int create_from = p_options["create_from"]; float threshold = p_options["threshold"]; Ref<Image> image; diff --git a/editor/import/resource_importer_bitmask.h b/editor/import/resource_importer_bitmask.h index 30564bf0fe..fcb152b47d 100644 --- a/editor/import/resource_importer_bitmask.h +++ b/editor/import/resource_importer_bitmask.h @@ -48,7 +48,7 @@ public: virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override; virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; virtual bool can_import_threaded() const override { return true; } diff --git a/editor/import/resource_importer_bmfont.cpp b/editor/import/resource_importer_bmfont.cpp index 085ca1362d..b7efdbb6d6 100644 --- a/editor/import/resource_importer_bmfont.cpp +++ b/editor/import/resource_importer_bmfont.cpp @@ -67,7 +67,7 @@ void ResourceImporterBMFont::get_import_options(const String &p_path, List<Impor r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "scaling_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled (Integer),Enabled (Fractional)"), TextServer::FIXED_SIZE_SCALE_ENABLED)); } -Error ResourceImporterBMFont::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterBMFont::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { print_verbose("Importing BMFont font from: " + p_source_file); Array fallbacks = p_options["fallbacks"]; diff --git a/editor/import/resource_importer_bmfont.h b/editor/import/resource_importer_bmfont.h index 48f036ff13..74fef9ff16 100644 --- a/editor/import/resource_importer_bmfont.h +++ b/editor/import/resource_importer_bmfont.h @@ -48,7 +48,7 @@ public: virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override; virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; virtual bool can_import_threaded() const override { return true; } diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp index c181011402..17f6070d35 100644 --- a/editor/import/resource_importer_csv_translation.cpp +++ b/editor/import/resource_importer_csv_translation.cpp @@ -72,7 +72,7 @@ void ResourceImporterCSVTranslation::get_import_options(const String &p_path, Li r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "delimiter", PROPERTY_HINT_ENUM, "Comma,Semicolon,Tab"), 0)); } -Error ResourceImporterCSVTranslation::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterCSVTranslation::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { bool compress = p_options["compress"]; String delimiter; @@ -147,6 +147,9 @@ Error ResourceImporterCSVTranslation::import(const String &p_source_file, const if (r_gen_files) { r_gen_files->push_back(save_path); } + + ResourceUID::ID save_id = hash64_murmur3_64(translations[i]->get_locale().hash64(), p_source_id); + ResourceSaver::set_uid(save_path, save_id); } return OK; diff --git a/editor/import/resource_importer_csv_translation.h b/editor/import/resource_importer_csv_translation.h index 9c83719ed1..63676c61a6 100644 --- a/editor/import/resource_importer_csv_translation.h +++ b/editor/import/resource_importer_csv_translation.h @@ -49,7 +49,7 @@ public: virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override; virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; virtual bool can_import_threaded() const override { return true; } diff --git a/editor/import/resource_importer_dynamic_font.cpp b/editor/import/resource_importer_dynamic_font.cpp index fa222b2790..a4a5e445e3 100644 --- a/editor/import/resource_importer_dynamic_font.cpp +++ b/editor/import/resource_importer_dynamic_font.cpp @@ -141,7 +141,7 @@ void ResourceImporterDynamicFont::show_advanced_options(const String &p_path) { DynamicFontImportSettingsDialog::get_singleton()->open_settings(p_path); } -Error ResourceImporterDynamicFont::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterDynamicFont::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { print_verbose("Importing dynamic font from: " + p_source_file); int antialiasing = p_options["antialiasing"]; diff --git a/editor/import/resource_importer_dynamic_font.h b/editor/import/resource_importer_dynamic_font.h index 7c7a16cf92..73ef96d583 100644 --- a/editor/import/resource_importer_dynamic_font.h +++ b/editor/import/resource_importer_dynamic_font.h @@ -58,7 +58,7 @@ public: bool has_advanced_options() const override; void show_advanced_options(const String &p_path) override; - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; virtual bool can_import_threaded() const override { return true; } diff --git a/editor/import/resource_importer_image.cpp b/editor/import/resource_importer_image.cpp index 4f6dd4e4ef..5a4f64d245 100644 --- a/editor/import/resource_importer_image.cpp +++ b/editor/import/resource_importer_image.cpp @@ -70,7 +70,7 @@ String ResourceImporterImage::get_preset_name(int p_idx) const { void ResourceImporterImage::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const { } -Error ResourceImporterImage::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterImage::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { Ref<FileAccess> f = FileAccess::open(p_source_file, FileAccess::READ); ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_OPEN, "Cannot open file from path '" + p_source_file + "'."); diff --git a/editor/import/resource_importer_image.h b/editor/import/resource_importer_image.h index dd395009c1..da1925bc5c 100644 --- a/editor/import/resource_importer_image.h +++ b/editor/import/resource_importer_image.h @@ -50,7 +50,7 @@ public: virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override; virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; virtual bool can_import_threaded() const override { return true; } diff --git a/editor/import/resource_importer_imagefont.cpp b/editor/import/resource_importer_imagefont.cpp index f01381904d..44ae2b5ff1 100644 --- a/editor/import/resource_importer_imagefont.cpp +++ b/editor/import/resource_importer_imagefont.cpp @@ -75,7 +75,7 @@ void ResourceImporterImageFont::get_import_options(const String &p_path, List<Im r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "scaling_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled (Integer),Enabled (Fractional)"), TextServer::FIXED_SIZE_SCALE_ENABLED)); } -Error ResourceImporterImageFont::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterImageFont::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { print_verbose("Importing image font from: " + p_source_file); int columns = p_options["columns"]; diff --git a/editor/import/resource_importer_imagefont.h b/editor/import/resource_importer_imagefont.h index 6b30a3cd6e..79e9455d6d 100644 --- a/editor/import/resource_importer_imagefont.h +++ b/editor/import/resource_importer_imagefont.h @@ -48,7 +48,7 @@ public: virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override; virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; virtual bool can_import_threaded() const override { return true; } diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp index 312195fcd7..0d0c89425d 100644 --- a/editor/import/resource_importer_layered_texture.cpp +++ b/editor/import/resource_importer_layered_texture.cpp @@ -289,7 +289,7 @@ void ResourceImporterLayeredTexture::_save_tex(Vector<Ref<Image>> p_images, cons } } -Error ResourceImporterLayeredTexture::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterLayeredTexture::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { int compress_mode = p_options["compress/mode"]; float lossy = p_options["compress/lossy_quality"]; bool high_quality = p_options["compress/high_quality"]; diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h index d8b5bc2d14..271f1f4543 100644 --- a/editor/import/resource_importer_layered_texture.h +++ b/editor/import/resource_importer_layered_texture.h @@ -112,7 +112,7 @@ public: void _save_tex(Vector<Ref<Image>> p_images, const String &p_to_path, int p_compress_mode, float p_lossy, Image::CompressMode p_vram_compression, Image::CompressSource p_csource, Image::UsedChannels used_channels, bool p_mipmaps, bool p_force_po2); - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; virtual bool are_import_settings_valid(const String &p_path, const Dictionary &p_meta) const override; virtual String get_import_settings_string() const override; diff --git a/editor/import/resource_importer_shader_file.cpp b/editor/import/resource_importer_shader_file.cpp index b7508e7644..639ce48f75 100644 --- a/editor/import/resource_importer_shader_file.cpp +++ b/editor/import/resource_importer_shader_file.cpp @@ -89,7 +89,7 @@ static String _include_function(const String &p_path, void *userpointer) { return file_inc->get_as_utf8_string(); } -Error ResourceImporterShaderFile::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterShaderFile::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { /* STEP 1, Read shader code */ ERR_FAIL_COND_V_EDMSG((OS::get_singleton()->get_current_rendering_method() == "gl_compatibility"), ERR_UNAVAILABLE, "Cannot import custom .glsl shaders when using the gl_compatibility rendering_method. Please switch to the forward_plus or mobile rendering methods to use custom shaders."); ERR_FAIL_COND_V_EDMSG((DisplayServer::get_singleton()->get_name() == "headless"), ERR_UNAVAILABLE, "Cannot import custom .glsl shaders when running in headless mode."); diff --git a/editor/import/resource_importer_shader_file.h b/editor/import/resource_importer_shader_file.h index b28dea36d6..440a3d86b4 100644 --- a/editor/import/resource_importer_shader_file.h +++ b/editor/import/resource_importer_shader_file.h @@ -49,7 +49,7 @@ public: virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override; virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; virtual bool can_import_threaded() const override { return true; } diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index 24a14c60ad..8d6f4e0a70 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -241,7 +241,10 @@ void ResourceImporterTexture::get_import_options(const String &p_path, List<Impo r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/normal_map_invert_y"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/hdr_as_srgb"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/hdr_clamp_exposure"), false)); - r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "process/size_limit", PROPERTY_HINT_RANGE, "0,4096,1"), 0)); + + // Maximum bound is the highest allowed value for lossy compression (the lowest common denominator). + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "process/size_limit", PROPERTY_HINT_RANGE, "0,16383,1"), 0)); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "detect_3d/compress_to", PROPERTY_HINT_ENUM, "Disabled,VRAM Compressed,Basis Universal"), (p_preset == PRESET_DETECT) ? 1 : 0)); // Do path based customization only if a path was passed. @@ -428,7 +431,7 @@ Dictionary ResourceImporterTexture::_load_editor_meta(const String &p_path) cons return f->get_var(); } -Error ResourceImporterTexture::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterTexture::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { // Parse import options. int32_t loader_flags = ImageFormatLoader::FLAG_NONE; @@ -454,7 +457,28 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String const bool normal_map_invert_y = p_options["process/normal_map_invert_y"]; // Support for texture streaming is not implemented yet. const bool stream = false; - const int size_limit = p_options["process/size_limit"]; + + int size_limit = p_options["process/size_limit"]; + bool using_fallback_size_limit = false; + if (size_limit == 0) { + using_fallback_size_limit = true; + // If no size limit is defined, use a fallback size limit to prevent textures from looking incorrect or failing to import. + switch (compress_mode) { + case COMPRESS_LOSSY: + // Maximum WebP size on either axis. + size_limit = 16383; + break; + case COMPRESS_BASIS_UNIVERSAL: + // Maximum Basis Universal size on either axis. + size_limit = 16384; + break; + default: + // As of June 2024, no GPU can correctly display a texture larger than 32768 pixels on either axis. + size_limit = 32768; + break; + } + } + const bool hdr_as_srgb = p_options["process/hdr_as_srgb"]; if (hdr_as_srgb) { loader_flags |= ImageFormatLoader::FLAG_FORCE_LINEAR; @@ -523,11 +547,19 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String int new_width = size_limit; int new_height = target_image->get_height() * new_width / target_image->get_width(); + if (using_fallback_size_limit) { + // Only warn if downsizing occurred when the user did not explicitly request it. + WARN_PRINT(vformat("%s: Texture was downsized on import as its width (%d pixels) exceeded the importable size limit (%d pixels).", p_source_file, target_image->get_width(), size_limit)); + } target_image->resize(new_width, new_height, Image::INTERPOLATE_CUBIC); } else { int new_height = size_limit; int new_width = target_image->get_width() * new_height / target_image->get_height(); + if (using_fallback_size_limit) { + // Only warn if downsizing occurred when the user did not explicitly request it. + WARN_PRINT(vformat("%s: Texture was downsized on import as its height (%d pixels) exceeded the importable size limit (%d pixels).", p_source_file, target_image->get_height(), size_limit)); + } target_image->resize(new_width, new_height, Image::INTERPOLATE_CUBIC); } diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h index 6c87cd0abb..8aa044f3c8 100644 --- a/editor/import/resource_importer_texture.h +++ b/editor/import/resource_importer_texture.h @@ -100,7 +100,7 @@ public: virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override; virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; virtual bool can_import_threaded() const override { return true; } diff --git a/editor/import/resource_importer_texture_atlas.cpp b/editor/import/resource_importer_texture_atlas.cpp index d6ce39f6a6..7e645cc0d0 100644 --- a/editor/import/resource_importer_texture_atlas.cpp +++ b/editor/import/resource_importer_texture_atlas.cpp @@ -91,7 +91,7 @@ String ResourceImporterTextureAtlas::get_option_group_file() const { return "atlas_file"; } -Error ResourceImporterTextureAtlas::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterTextureAtlas::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { /* If this happens, it's because the atlas_file field was not filled, so just import a broken texture */ //use an xpm because it's size independent, the editor images are vector and size dependent diff --git a/editor/import/resource_importer_texture_atlas.h b/editor/import/resource_importer_texture_atlas.h index e4ad9ac230..943f221679 100644 --- a/editor/import/resource_importer_texture_atlas.h +++ b/editor/import/resource_importer_texture_atlas.h @@ -64,7 +64,7 @@ public: virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; virtual String get_option_group_file() const override; - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; virtual Error import_group_file(const String &p_group_file, const HashMap<String, HashMap<StringName, Variant>> &p_source_file_options, const HashMap<String, String> &p_base_paths) override; virtual bool can_import_threaded() const override { return true; } diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp index 2654952e8a..f500ec4a07 100644 --- a/editor/import/resource_importer_wav.cpp +++ b/editor/import/resource_importer_wav.cpp @@ -94,7 +94,7 @@ void ResourceImporterWAV::get_import_options(const String &p_path, List<ImportOp r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "PCM (Uncompressed),IMA ADPCM,Quite OK Audio"), 2)); } -Error ResourceImporterWAV::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterWAV::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { /* STEP 1, READ WAVE FILE */ Error err; diff --git a/editor/import/resource_importer_wav.h b/editor/import/resource_importer_wav.h index 2253756554..361541c6c1 100644 --- a/editor/import/resource_importer_wav.h +++ b/editor/import/resource_importer_wav.h @@ -140,7 +140,7 @@ public: } } - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; virtual bool can_import_threaded() const override { return true; } diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 34c0040cb7..096e92e235 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -45,6 +45,7 @@ #include "scene/3d/skeleton_3d.h" #include "scene/animation/animation_player.h" #include "scene/gui/check_box.h" +#include "scene/gui/grid_container.h" #include "scene/gui/menu_button.h" #include "scene/gui/option_button.h" #include "scene/gui/panel.h" @@ -1265,7 +1266,7 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() { open_file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); open_file->connect("file_selected", callable_mp(this, &AnimationNodeBlendTreeEditor::_file_opened)); - animation_node_inspector_plugin = Ref<EditorInspectorPluginAnimationNodeAnimation>(memnew(EditorInspectorPluginAnimationNodeAnimation)); + animation_node_inspector_plugin.instantiate(); EditorInspector::add_inspector_plugin(animation_node_inspector_plugin); } @@ -1397,32 +1398,30 @@ bool EditorInspectorPluginAnimationNodeAnimation::parse_property(Object *p_objec } AnimationNodeAnimationEditorDialog::AnimationNodeAnimationEditorDialog() { - set_title(TTR("Select Markers...")); - VBoxContainer *vbox = memnew(VBoxContainer); - add_child(vbox); - vbox->set_offsets_preset(Control::PRESET_FULL_RECT); - - HBoxContainer *container_start = memnew(HBoxContainer); - vbox->add_child(container_start); - Label *label_start = memnew(Label); - container_start->add_child(label_start); + set_title(TTR("Select Markers")); + + GridContainer *grid = memnew(GridContainer); + grid->set_columns(2); + grid->set_offsets_preset(Control::PRESET_FULL_RECT); + add_child(grid); + + Label *label_start = memnew(Label(TTR("Start Marker"))); + grid->add_child(label_start); label_start->set_h_size_flags(Control::SIZE_EXPAND_FILL); label_start->set_stretch_ratio(1); - label_start->set_text(TTR("Start Marker")); select_start = memnew(OptionButton); - container_start->add_child(select_start); + select_start->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); + grid->add_child(select_start); select_start->set_h_size_flags(Control::SIZE_EXPAND_FILL); select_start->set_stretch_ratio(2); - HBoxContainer *container_end = memnew(HBoxContainer); - vbox->add_child(container_end); - Label *label_end = memnew(Label); - container_end->add_child(label_end); + Label *label_end = memnew(Label(TTR("End Marker"))); + grid->add_child(label_end); label_end->set_h_size_flags(Control::SIZE_EXPAND_FILL); label_end->set_stretch_ratio(1); - label_end->set_text(TTR("End Marker")); select_end = memnew(OptionButton); - container_end->add_child(select_end); + select_end->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); + grid->add_child(select_end); select_end->set_h_size_flags(Control::SIZE_EXPAND_FILL); select_end->set_stretch_ratio(2); } diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index d089aedc63..4edd021b4d 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -580,8 +580,10 @@ float AnimationPlayerEditor::_get_editor_step() const { const Ref<Animation> anim = player->get_animation(current); ERR_FAIL_COND_V(anim.is_null(), 0.0); + float step = track_editor->get_snap_unit(); + // Use more precise snapping when holding Shift - return Input::get_singleton()->is_key_pressed(Key::SHIFT) ? anim->get_step() * 0.25 : anim->get_step(); + return Input::get_singleton()->is_key_pressed(Key::SHIFT) ? step * 0.25 : step; } void AnimationPlayerEditor::_animation_name_edited() { diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index e3cf3dbbf2..62793fbcb5 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -5620,7 +5620,7 @@ CanvasItemEditor::CanvasItemEditor() { snap_dialog->connect(SceneStringName(confirmed), callable_mp(this, &CanvasItemEditor::_snap_changed)); add_child(snap_dialog); - select_sb = Ref<StyleBoxTexture>(memnew(StyleBoxTexture)); + select_sb.instantiate(); selection_menu = memnew(PopupMenu); add_child(selection_menu); diff --git a/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp index 39ae020d53..5a6527f876 100644 --- a/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp +++ b/editor/plugins/gizmos/marker_3d_gizmo_plugin.cpp @@ -36,7 +36,7 @@ #include "scene/3d/marker_3d.h" Marker3DGizmoPlugin::Marker3DGizmoPlugin() { - pos3d_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + pos3d_mesh.instantiate(); Vector<Vector3> cursor_points; Vector<Color> cursor_colors; diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp index 429add4540..e3b59f9bfb 100644 --- a/editor/plugins/light_occluder_2d_editor_plugin.cpp +++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp @@ -35,8 +35,8 @@ Ref<OccluderPolygon2D> LightOccluder2DEditor::_ensure_occluder() const { Ref<OccluderPolygon2D> occluder = node->get_occluder_polygon(); - if (!occluder.is_valid()) { - occluder = Ref<OccluderPolygon2D>(memnew(OccluderPolygon2D)); + if (occluder.is_null()) { + occluder.instantiate(); node->set_occluder_polygon(occluder); } return occluder; diff --git a/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp b/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp index 2eaab0fcbd..94ad20f05a 100644 --- a/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp +++ b/editor/plugins/navigation_obstacle_3d_editor_plugin.cpp @@ -30,144 +30,502 @@ #include "navigation_obstacle_3d_editor_plugin.h" -#include "canvas_item_editor_plugin.h" -#include "core/input/input.h" -#include "core/io/file_access.h" +#include "core/config/project_settings.h" #include "core/math/geometry_2d.h" -#include "core/os/keyboard.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_string_names.h" #include "editor/editor_undo_redo_manager.h" -#include "node_3d_editor_plugin.h" -#include "scene/3d/camera_3d.h" -#include "scene/gui/separator.h" +#include "editor/plugins/node_3d_editor_plugin.h" +#include "scene/3d/navigation_obstacle_3d.h" +#include "scene/gui/button.h" +#include "scene/gui/dialogs.h" +#include "servers/navigation_server_3d.h" + +bool NavigationObstacle3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { + return Object::cast_to<NavigationObstacle3D>(p_spatial) != nullptr; +} + +String NavigationObstacle3DGizmoPlugin::get_gizmo_name() const { + return "NavigationObstacle3D"; +} + +void NavigationObstacle3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { + p_gizmo->clear(); + + if (!p_gizmo->is_selected() && get_state() == HIDDEN) { + return; + } + + NavigationObstacle3D *obstacle = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d()); + + if (!obstacle) { + return; + } + + const Vector<Vector3> &vertices = obstacle->get_vertices(); + if (vertices.is_empty()) { + return; + } + + float height = obstacle->get_height(); + Basis gbi = obstacle->get_global_basis().inverse(); + + const int vertex_count = vertices.size(); + + Vector<Vector3> lines_mesh_vertices; + lines_mesh_vertices.resize(vertex_count * 8); + Vector3 *lines_mesh_vertices_ptrw = lines_mesh_vertices.ptrw(); + + int vertex_index = 0; + + for (int i = 0; i < vertex_count; i++) { + Vector3 point = vertices[i]; + Vector3 next_point = vertices[(i + 1) % vertex_count]; + + Vector3 direction = next_point.direction_to(point); + Vector3 arrow_dir = direction.cross(Vector3(0.0, 1.0, 0.0)); + Vector3 edge_middle = point + ((next_point - point) * 0.5); + + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(edge_middle); + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(edge_middle + (arrow_dir * 0.5)); + + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(point); + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(next_point); + + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(Vector3(point.x, height, point.z)); + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(Vector3(next_point.x, height, next_point.z)); + + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(point); + lines_mesh_vertices_ptrw[vertex_index++] = gbi.xform(Vector3(point.x, height, point.z)); + } + + Vector<Vector2> polygon_2d_vertices; + polygon_2d_vertices.resize(vertex_count); + for (int i = 0; i < vertex_count; i++) { + const Vector3 &vert = vertices[i]; + polygon_2d_vertices.write[i] = Vector2(vert.x, vert.z); + } + Vector<int> triangulated_polygon_2d_indices = Geometry2D::triangulate_polygon(polygon_2d_vertices); + + NavigationServer3D *ns3d = NavigationServer3D::get_singleton(); + + if (triangulated_polygon_2d_indices.is_empty()) { + p_gizmo->add_lines(lines_mesh_vertices, ns3d->get_debug_navigation_avoidance_static_obstacle_pushin_edge_material()); + } else { + p_gizmo->add_lines(lines_mesh_vertices, ns3d->get_debug_navigation_avoidance_static_obstacle_pushout_edge_material()); + } + p_gizmo->add_collision_segments(lines_mesh_vertices); + + if (p_gizmo->is_selected()) { + NavigationObstacle3DEditorPlugin::singleton->redraw(); + } +} + +bool NavigationObstacle3DGizmoPlugin::can_be_hidden() const { + return true; +} + +int NavigationObstacle3DGizmoPlugin::get_priority() const { + return -1; +} + +int NavigationObstacle3DGizmoPlugin::subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const { + if (NavigationObstacle3DEditorPlugin::singleton->get_mode() != 1) { // MODE_EDIT + return -1; + } + + NavigationObstacle3D *obstacle_node = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d()); + ERR_FAIL_NULL_V(obstacle_node, -1); + + Transform3D gt = Transform3D(Basis(), obstacle_node->get_global_position()); + const Vector<Vector3> &vertices = obstacle_node->get_vertices(); + + for (int idx = 0; idx < vertices.size(); ++idx) { + Vector3 pos = gt.xform(vertices[idx]); + if (p_camera->unproject_position(pos).distance_to(p_point) < 20) { + return idx; + } + } + + return -1; +} + +Vector<int> NavigationObstacle3DGizmoPlugin::subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const { + Vector<int> contained_points; + if (NavigationObstacle3DEditorPlugin::singleton->get_mode() != 1) { // MODE_EDIT + return contained_points; + } + + NavigationObstacle3D *obstacle_node = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d()); + ERR_FAIL_NULL_V(obstacle_node, contained_points); + + Transform3D gt = Transform3D(Basis(), obstacle_node->get_global_position()); + const Vector<Vector3> &vertices = obstacle_node->get_vertices(); + + for (int idx = 0; idx < vertices.size(); ++idx) { + Vector3 pos = gt.xform(vertices[idx]); + bool is_contained_in_frustum = true; + for (int i = 0; i < p_frustum.size(); ++i) { + if (p_frustum[i].distance_to(pos) > 0) { + is_contained_in_frustum = false; + break; + } + } + + if (is_contained_in_frustum) { + contained_points.push_back(idx); + } + } + + return contained_points; +} + +Transform3D NavigationObstacle3DGizmoPlugin::get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const { + NavigationObstacle3D *obstacle_node = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d()); + ERR_FAIL_NULL_V(obstacle_node, Transform3D()); + + const Vector<Vector3> &vertices = obstacle_node->get_vertices(); + ERR_FAIL_INDEX_V(p_id, vertices.size(), Transform3D()); + + Basis gbi = obstacle_node->get_global_basis().inverse(); + + Transform3D subgizmo_transform = Transform3D(Basis(), gbi.xform(vertices[p_id])); + return subgizmo_transform; +} + +void NavigationObstacle3DGizmoPlugin::set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) { + NavigationObstacle3D *obstacle_node = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d()); + ERR_FAIL_NULL(obstacle_node); + + Basis gb = obstacle_node->get_global_basis(); + + Vector3 new_vertex_pos = p_transform.origin; + + Vector<Vector3> vertices = obstacle_node->get_vertices(); + ERR_FAIL_INDEX(p_id, vertices.size()); -void NavigationObstacle3DEditor::_notification(int p_what) { + Vector3 vertex = gb.xform(new_vertex_pos); + vertex.y = 0.0; + vertices.write[p_id] = vertex; + + obstacle_node->set_vertices(vertices); +} + +void NavigationObstacle3DGizmoPlugin::commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel) { + NavigationObstacle3D *obstacle_node = Object::cast_to<NavigationObstacle3D>(p_gizmo->get_node_3d()); + ERR_FAIL_NULL(obstacle_node); + + Basis gb = obstacle_node->get_global_basis(); + + Vector<Vector3> vertices = obstacle_node->get_vertices(); + Vector<Vector3> restore_vertices = vertices; + + for (int i = 0; i < p_ids.size(); ++i) { + const int idx = p_ids[i]; + Vector3 vertex = gb.xform(p_restore[i].origin); + vertex.y = 0.0; + restore_vertices.write[idx] = vertex; + } + + if (p_cancel) { + obstacle_node->set_vertices(restore_vertices); + return; + } + + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Set Obstacle Vertices")); + undo_redo->add_do_method(obstacle_node, "set_vertices", vertices); + undo_redo->add_undo_method(obstacle_node, "set_vertices", restore_vertices); + undo_redo->commit_action(); +} + +NavigationObstacle3DGizmoPlugin::NavigationObstacle3DGizmoPlugin() { + current_state = VISIBLE; +} + +void NavigationObstacle3DEditorPlugin::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + _update_theme(); + } break; + case NOTIFICATION_READY: { - button_create->set_button_icon(get_editor_theme_icon(SNAME("Edit"))); - button_edit->set_button_icon(get_editor_theme_icon(SNAME("MovePoint"))); + _update_theme(); button_edit->set_pressed(true); - get_tree()->connect("node_removed", callable_mp(this, &NavigationObstacle3DEditor::_node_removed)); + get_tree()->connect("node_removed", callable_mp(this, &NavigationObstacle3DEditorPlugin::_node_removed)); + EditorNode::get_singleton()->get_gui_base()->connect(SceneStringName(theme_changed), callable_mp(this, &NavigationObstacle3DEditorPlugin::_update_theme)); + } break; + case NOTIFICATION_EXIT_TREE: { + get_tree()->disconnect("node_removed", callable_mp(this, &NavigationObstacle3DEditorPlugin::_node_removed)); + EditorNode::get_singleton()->get_gui_base()->disconnect(SceneStringName(theme_changed), callable_mp(this, &NavigationObstacle3DEditorPlugin::_update_theme)); } break; } } -void NavigationObstacle3DEditor::_node_removed(Node *p_node) { - if (p_node == obstacle_node) { - obstacle_node = nullptr; - if (point_lines_meshinstance->get_parent() == p_node) { - p_node->remove_child(point_lines_meshinstance); +void NavigationObstacle3DEditorPlugin::edit(Object *p_object) { + obstacle_node = Object::cast_to<NavigationObstacle3D>(p_object); + + RenderingServer *rs = RenderingServer::get_singleton(); + + if (obstacle_node) { + if (obstacle_node->get_vertices().is_empty()) { + set_mode(MODE_CREATE); + } else { + set_mode(MODE_EDIT); } - hide(); + wip_vertices.clear(); + wip_active = false; + edited_point = -1; + + rs->instance_set_scenario(point_lines_instance_rid, obstacle_node->get_world_3d()->get_scenario()); + rs->instance_set_scenario(point_handles_instance_rid, obstacle_node->get_world_3d()->get_scenario()); + + redraw(); + + } else { + obstacle_node = nullptr; + + rs->mesh_clear(point_lines_mesh_rid); + rs->mesh_clear(point_handle_mesh_rid); + rs->instance_set_scenario(point_lines_instance_rid, RID()); + rs->instance_set_scenario(point_handles_instance_rid, RID()); } } -void NavigationObstacle3DEditor::_menu_option(int p_option) { - switch (p_option) { - case MODE_CREATE: { - mode = MODE_CREATE; - button_create->set_pressed(true); - button_edit->set_pressed(false); - } break; - case MODE_EDIT: { - mode = MODE_EDIT; - button_create->set_pressed(false); - button_edit->set_pressed(true); - } break; +bool NavigationObstacle3DEditorPlugin::handles(Object *p_object) const { + return Object::cast_to<NavigationObstacle3D>(p_object); +} + +void NavigationObstacle3DEditorPlugin::make_visible(bool p_visible) { + if (p_visible) { + obstacle_editor->show(); + } else { + obstacle_editor->hide(); + edit(nullptr); } } -void NavigationObstacle3DEditor::_wip_close() { - ERR_FAIL_NULL_MSG(obstacle_node, "Edited NavigationObstacle3D is not valid."); +void NavigationObstacle3DEditorPlugin::action_flip_vertices() { + if (!obstacle_node) { + return; + } + + Vector<Vector3> flipped_vertices = obstacle_node->get_vertices(); + flipped_vertices.reverse(); + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Set NavigationObstacle3D Vertices")); + undo_redo->create_action(TTR("Edit Obstacle (Flip Winding)")); + undo_redo->add_do_method(obstacle_node, "set_vertices", flipped_vertices); undo_redo->add_undo_method(obstacle_node, "set_vertices", obstacle_node->get_vertices()); + undo_redo->commit_action(); - PackedVector3Array polygon_3d_vertices; - Vector<int> triangulated_polygon_2d_indices = Geometry2D::triangulate_polygon(wip); + obstacle_node->update_gizmos(); +} - if (!triangulated_polygon_2d_indices.is_empty()) { - polygon_3d_vertices.resize(wip.size()); - Vector3 *polygon_3d_vertices_ptr = polygon_3d_vertices.ptrw(); - for (int i = 0; i < wip.size(); i++) { - const Vector2 &vert = wip[i]; - polygon_3d_vertices_ptr[i] = Vector3(vert.x, 0.0, vert.y); - } +void NavigationObstacle3DEditorPlugin::action_clear_vertices() { + if (!obstacle_node) { + return; } - undo_redo->add_do_method(obstacle_node, "set_vertices", polygon_3d_vertices); - undo_redo->add_do_method(this, "_polygon_draw"); - undo_redo->add_undo_method(this, "_polygon_draw"); - wip.clear(); + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Edit Obstacle (Clear Vertices)")); + undo_redo->add_do_method(obstacle_node, "set_vertices", Vector<Vector3>()); + undo_redo->add_undo_method(obstacle_node, "set_vertices", obstacle_node->get_vertices()); + undo_redo->commit_action(); + + obstacle_node->update_gizmos(); + edit(obstacle_node); +} + +void NavigationObstacle3DEditorPlugin::_update_theme() { + button_create->set_tooltip_text(TTR("Add Vertex")); + button_edit->set_tooltip_text(TTR("Edit Vertex")); + button_delete->set_tooltip_text(TTR("Delete Vertex")); + button_flip->set_tooltip_text(TTR("Flip Winding")); + button_clear->set_tooltip_text(TTR("Clear Vertices")); + button_create->set_button_icon(button_create->get_editor_theme_icon(SNAME("CurveCreate"))); + button_edit->set_button_icon(button_edit->get_editor_theme_icon(SNAME("CurveEdit"))); + button_delete->set_button_icon(button_delete->get_editor_theme_icon(SNAME("CurveDelete"))); + button_flip->set_button_icon(button_flip->get_editor_theme_icon(SNAME("FlipWinding"))); + button_clear->set_button_icon(button_clear->get_editor_theme_icon(SNAME("Clear"))); +} + +void NavigationObstacle3DEditorPlugin::_node_removed(Node *p_node) { + if (obstacle_node == p_node) { + obstacle_node = nullptr; + + RenderingServer *rs = RenderingServer::get_singleton(); + rs->mesh_clear(point_lines_mesh_rid); + rs->mesh_clear(point_handle_mesh_rid); + + obstacle_editor->hide(); + } +} + +void NavigationObstacle3DEditorPlugin::set_mode(int p_option) { + if (p_option == NavigationObstacle3DEditorPlugin::ACTION_FLIP) { + button_flip->set_pressed(false); + action_flip_vertices(); + return; + } + + if (p_option == NavigationObstacle3DEditorPlugin::ACTION_CLEAR) { + button_clear->set_pressed(false); + button_clear_dialog->reset_size(); + button_clear_dialog->popup_centered(); + return; + } + + mode = p_option; + + button_create->set_pressed(p_option == NavigationObstacle3DEditorPlugin::MODE_CREATE); + button_edit->set_pressed(p_option == NavigationObstacle3DEditorPlugin::MODE_EDIT); + button_delete->set_pressed(p_option == NavigationObstacle3DEditorPlugin::MODE_DELETE); + button_flip->set_pressed(false); + button_clear->set_pressed(false); +} + +void NavigationObstacle3DEditorPlugin::_wip_cancel() { + wip_vertices.clear(); wip_active = false; - mode = MODE_EDIT; - button_edit->set_pressed(true); - button_create->set_pressed(false); + edited_point = -1; - undo_redo->commit_action(); + + redraw(); } -EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { +void NavigationObstacle3DEditorPlugin::_wip_close() { + ERR_FAIL_NULL_MSG(obstacle_node, "Edited NavigationObstacle3D is not valid."); + + Vector<Vector2> wip_2d_vertices; + wip_2d_vertices.resize(wip_vertices.size()); + for (int i = 0; i < wip_vertices.size(); i++) { + const Vector3 &vert = wip_vertices[i]; + wip_2d_vertices.write[i] = Vector2(vert.x, vert.z); + } + Vector<int> triangulated_polygon_2d_indices = Geometry2D::triangulate_polygon(wip_2d_vertices); + + if (!triangulated_polygon_2d_indices.is_empty()) { + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Set Obstacle Vertices")); + undo_redo->add_do_method(obstacle_node, "set_vertices", wip_vertices); + undo_redo->add_undo_method(obstacle_node, "set_vertices", obstacle_node->get_vertices()); + undo_redo->commit_action(); + + wip_vertices.clear(); + wip_active = false; + //mode = MODE_EDIT; + NavigationObstacle3DEditorPlugin::singleton->set_mode(NavigationObstacle3DEditorPlugin::MODE_EDIT); + button_edit->set_pressed(true); + button_create->set_pressed(false); + edited_point = -1; + } +} + +EditorPlugin::AfterGUIInput NavigationObstacle3DEditorPlugin::forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) { if (!obstacle_node) { return EditorPlugin::AFTER_GUI_INPUT_PASS; } - Transform3D gt = obstacle_node->get_global_transform(); - Transform3D gi = gt.affine_inverse(); - Plane p(Vector3(0.0, 1.0, 0.0), gt.origin); + if (!obstacle_node->is_visible_in_tree()) { + return EditorPlugin::AFTER_GUI_INPUT_PASS; + } + + Ref<InputEventMouse> mouse_event = p_event; + + if (mouse_event.is_null()) { + return EditorPlugin::AFTER_GUI_INPUT_PASS; + } Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { - Vector2 gpoint = mb->get_position(); - Vector3 ray_from = p_camera->project_ray_origin(gpoint); - Vector3 ray_dir = p_camera->project_ray_normal(gpoint); + Vector2 mouse_position = mb->get_position(); + Vector3 ray_from = p_camera->project_ray_origin(mouse_position); + Vector3 ray_dir = p_camera->project_ray_normal(mouse_position); + + Transform3D gt = Transform3D(Basis(), obstacle_node->get_global_position()); + Transform3D gi = gt.affine_inverse(); + Plane projection_plane(Vector3(0.0, 1.0, 0.0), gt.origin); Vector3 spoint; - if (!p.intersects_ray(ray_from, ray_dir, &spoint)) { + if (!projection_plane.intersects_ray(ray_from, ray_dir, &spoint)) { return EditorPlugin::AFTER_GUI_INPUT_PASS; } spoint = gi.xform(spoint); - Vector2 cpoint(spoint.x, spoint.z); - - //DO NOT snap here, it's confusing in 3D for adding points. - //Let the snap happen when the point is being moved, instead. - //cpoint = CanvasItemEditor::get_singleton()->snap_point(cpoint); + Vector3 cpoint = Vector3(spoint.x, 0.0, spoint.z); + Vector<Vector3> obstacle_vertices = obstacle_node->get_vertices(); - PackedVector2Array poly = _get_polygon(); - - //first check if a point is to be added (segment split) real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius"); switch (mode) { case MODE_CREATE: { if (mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) { + if (obstacle_vertices.size() >= 3) { + int closest_idx = -1; + Vector2 closest_edge_point; + real_t closest_dist = 1e10; + for (int i = 0; i < obstacle_vertices.size(); i++) { + Vector2 points[2] = { + p_camera->unproject_position(gt.xform(obstacle_vertices[i])), + p_camera->unproject_position(gt.xform(obstacle_vertices[(i + 1) % obstacle_vertices.size()])) + }; + + Vector2 cp = Geometry2D::get_closest_point_to_segment(mouse_position, points); + if (cp.distance_squared_to(points[0]) < grab_threshold || cp.distance_squared_to(points[1]) < grab_threshold) { + continue; // Skip edge as clicked point is too close to existing vertex. + } + + real_t d = cp.distance_to(mouse_position); + if (d < closest_dist && d < grab_threshold) { + closest_dist = d; + closest_edge_point = cp; + closest_idx = i; + } + } + if (closest_idx >= 0) { + edited_point = -1; + Vector3 _ray_from = p_camera->project_ray_origin(closest_edge_point); + Vector3 _ray_dir = p_camera->project_ray_normal(closest_edge_point); + Vector3 edge_intersection_point; + if (projection_plane.intersects_ray(_ray_from, _ray_dir, &edge_intersection_point)) { + edge_intersection_point = gi.xform(edge_intersection_point); + + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Edit Obstacle (Add Vertex)")); + undo_redo->add_undo_method(obstacle_node, "set_vertices", obstacle_vertices); + obstacle_vertices.insert(closest_idx + 1, edge_intersection_point); + undo_redo->add_do_method(obstacle_node, "set_vertices", obstacle_vertices); + undo_redo->commit_action(); + redraw(); + return EditorPlugin::AFTER_GUI_INPUT_STOP; + } + } + } if (!wip_active) { - wip.clear(); - wip.push_back(cpoint); + wip_vertices.clear(); + wip_vertices.push_back(cpoint); wip_active = true; edited_point_pos = cpoint; snap_ignore = false; - _polygon_draw(); + redraw(); edited_point = 1; return EditorPlugin::AFTER_GUI_INPUT_STOP; } else { - if (wip.size() > 1 && p_camera->unproject_position(gt.xform(Vector3(wip[0].x, 0.0, wip[0].y))).distance_to(gpoint) < grab_threshold) { - //wip closed + if (wip_vertices.size() > 1 && p_camera->unproject_position(gt.xform(wip_vertices[0])).distance_to(mouse_position) < grab_threshold) { _wip_close(); return EditorPlugin::AFTER_GUI_INPUT_STOP; } else { - wip.push_back(cpoint); - edited_point = wip.size(); + wip_vertices.push_back(cpoint); + edited_point = wip_vertices.size(); snap_ignore = false; - _polygon_draw(); + redraw(); return EditorPlugin::AFTER_GUI_INPUT_STOP; } } @@ -181,13 +539,11 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam if (mb->get_button_index() == MouseButton::LEFT) { if (mb->is_pressed()) { if (mb->is_ctrl_pressed()) { - if (poly.size() < 3) { + if (obstacle_vertices.size() < 3) { EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Edit Vertices")); + undo_redo->create_action(TTR("Edit Obstacle (Add Vertex)")); undo_redo->add_undo_method(obstacle_node, "set_vertices", obstacle_node->get_vertices()); - poly.push_back(cpoint); - undo_redo->add_do_method(this, "_polygon_draw"); - undo_redo->add_undo_method(this, "_polygon_draw"); + obstacle_vertices.push_back(cpoint); undo_redo->commit_action(); return EditorPlugin::AFTER_GUI_INPUT_STOP; } @@ -196,18 +552,18 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam int closest_idx = -1; Vector2 closest_pos; real_t closest_dist = 1e10; - for (int i = 0; i < poly.size(); i++) { + for (int i = 0; i < obstacle_vertices.size(); i++) { Vector2 points[2] = { - p_camera->unproject_position(gt.xform(Vector3(poly[i].x, 0.0, poly[i].y))), - p_camera->unproject_position(gt.xform(Vector3(poly[(i + 1) % poly.size()].x, 0.0, poly[(i + 1) % poly.size()].y))) + p_camera->unproject_position(gt.xform(obstacle_vertices[i])), + p_camera->unproject_position(gt.xform(obstacle_vertices[(i + 1) % obstacle_vertices.size()])) }; - Vector2 cp = Geometry2D::get_closest_point_to_segment(gpoint, points); + Vector2 cp = Geometry2D::get_closest_point_to_segment(mouse_position, points); if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2) { continue; //not valid to reuse point } - real_t d = cp.distance_to(gpoint); + real_t d = cp.distance_to(mouse_position); if (d < closest_dist && d < grab_threshold) { closest_dist = d; closest_pos = cp; @@ -216,26 +572,24 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam } if (closest_idx >= 0) { - pre_move_edit = poly; - poly.insert(closest_idx + 1, cpoint); + pre_move_edit = obstacle_vertices; + obstacle_vertices.insert(closest_idx + 1, cpoint); edited_point = closest_idx + 1; edited_point_pos = cpoint; - _set_polygon(poly); - _polygon_draw(); + obstacle_node->set_vertices(obstacle_vertices); + redraw(); snap_ignore = true; return EditorPlugin::AFTER_GUI_INPUT_STOP; } } else { - //look for points to move - int closest_idx = -1; Vector2 closest_pos; real_t closest_dist = 1e10; - for (int i = 0; i < poly.size(); i++) { - Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, 0.0, poly[i].y))); + for (int i = 0; i < obstacle_vertices.size(); i++) { + Vector2 cp = p_camera->unproject_position(gt.xform(obstacle_vertices[i])); - real_t d = cp.distance_to(gpoint); + real_t d = cp.distance_to(mouse_position); if (d < closest_dist && d < grab_threshold) { closest_dist = d; closest_pos = cp; @@ -244,10 +598,10 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam } if (closest_idx >= 0) { - pre_move_edit = poly; + pre_move_edit = obstacle_vertices; edited_point = closest_idx; - edited_point_pos = poly[closest_idx]; - _polygon_draw(); + edited_point_pos = obstacle_vertices[closest_idx]; + redraw(); snap_ignore = false; return EditorPlugin::AFTER_GUI_INPUT_STOP; } @@ -256,16 +610,13 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam snap_ignore = false; if (edited_point != -1) { - //apply + ERR_FAIL_INDEX_V(edited_point, obstacle_vertices.size(), EditorPlugin::AFTER_GUI_INPUT_PASS); + obstacle_vertices.write[edited_point] = edited_point_pos; - ERR_FAIL_INDEX_V(edited_point, poly.size(), EditorPlugin::AFTER_GUI_INPUT_PASS); - poly.write[edited_point] = edited_point_pos; EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Edit Poly")); - //undo_redo->add_do_method(obj, "set_polygon", poly); - //undo_redo->add_undo_method(obj, "set_polygon", pre_move_edit); - undo_redo->add_do_method(this, "_polygon_draw"); - undo_redo->add_undo_method(this, "_polygon_draw"); + undo_redo->create_action(TTR("Edit Obstacle (Move Vertex)")); + undo_redo->add_undo_method(obstacle_node, "set_vertices", obstacle_node->get_vertices()); + undo_redo->add_do_method(obstacle_node, "set_vertices", obstacle_vertices); undo_redo->commit_action(); edited_point = -1; @@ -273,30 +624,31 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam } } } - if (mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed() && edited_point == -1) { + + } break; + + case MODE_DELETE: { + if (mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) { int closest_idx = -1; - Vector2 closest_pos; real_t closest_dist = 1e10; - for (int i = 0; i < poly.size(); i++) { - Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, 0.0, poly[i].y))); - - real_t d = cp.distance_to(gpoint); + for (int i = 0; i < obstacle_vertices.size(); i++) { + Vector2 point = p_camera->unproject_position(gt.xform(obstacle_vertices[i])); + real_t d = point.distance_to(mouse_position); if (d < closest_dist && d < grab_threshold) { closest_dist = d; - closest_pos = cp; closest_idx = i; } } if (closest_idx >= 0) { + edited_point = -1; EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Edit Poly (Remove Point)")); - //undo_redo->add_undo_method(obj, "set_polygon", poly); - poly.remove_at(closest_idx); - //undo_redo->add_do_method(obj, "set_polygon", poly); - undo_redo->add_do_method(this, "_polygon_draw"); - undo_redo->add_undo_method(this, "_polygon_draw"); + undo_redo->create_action(TTR("Edit Obstacle (Remove Vertex)")); + undo_redo->add_undo_method(obstacle_node, "set_vertices", obstacle_vertices); + obstacle_vertices.remove_at(closest_idx); + undo_redo->add_do_method(obstacle_node, "set_vertices", obstacle_vertices); undo_redo->commit_action(); + redraw(); return EditorPlugin::AFTER_GUI_INPUT_STOP; } } @@ -309,20 +661,24 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam if (mm.is_valid()) { if (edited_point != -1 && (wip_active || mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) { - Vector2 gpoint = mm->get_position(); + Vector2 mouse_position = mm->get_position(); + + Vector3 ray_from = p_camera->project_ray_origin(mouse_position); + Vector3 ray_dir = p_camera->project_ray_normal(mouse_position); - Vector3 ray_from = p_camera->project_ray_origin(gpoint); - Vector3 ray_dir = p_camera->project_ray_normal(gpoint); + Transform3D gt = Transform3D(Basis(), obstacle_node->get_global_position()); + Transform3D gi = gt.affine_inverse(); + Plane projection_plane(Vector3(0.0, 1.0, 0.0), gt.origin); - Vector3 spoint; + Vector3 intersection_point; - if (!p.intersects_ray(ray_from, ray_dir, &spoint)) { + if (!projection_plane.intersects_ray(ray_from, ray_dir, &intersection_point)) { return EditorPlugin::AFTER_GUI_INPUT_PASS; } - spoint = gi.xform(spoint); + intersection_point = gi.xform(intersection_point); - Vector2 cpoint(spoint.x, spoint.z); + Vector2 cpoint(intersection_point.x, intersection_point.z); if (snap_ignore && !Input::get_singleton()->is_key_pressed(Key::CTRL)) { snap_ignore = false; @@ -331,272 +687,217 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam if (!snap_ignore && Node3DEditor::get_singleton()->is_snap_enabled()) { cpoint = cpoint.snappedf(Node3DEditor::get_singleton()->get_translate_snap()); } - edited_point_pos = cpoint; + edited_point_pos = Vector3(cpoint.x, 0.0, cpoint.y); - _polygon_draw(); + redraw(); } } - return EditorPlugin::AFTER_GUI_INPUT_PASS; -} + Ref<InputEventKey> k = p_event; -PackedVector2Array NavigationObstacle3DEditor::_get_polygon() { - ERR_FAIL_NULL_V_MSG(obstacle_node, PackedVector2Array(), "Edited object is not valid."); - return PackedVector2Array(obstacle_node->call("get_polygon")); -} + if (k.is_valid() && k->is_pressed()) { + if (wip_active && k->get_keycode() == Key::ENTER) { + _wip_close(); + } else if (wip_active && k->get_keycode() == Key::ESCAPE) { + _wip_cancel(); + } + } -void NavigationObstacle3DEditor::_set_polygon(const PackedVector2Array &p_poly) { - ERR_FAIL_NULL_MSG(obstacle_node, "Edited object is not valid."); - obstacle_node->call("set_polygon", p_poly); + return EditorPlugin::AFTER_GUI_INPUT_PASS; } -void NavigationObstacle3DEditor::_polygon_draw() { +void NavigationObstacle3DEditorPlugin::redraw() { if (!obstacle_node) { return; } + RenderingServer *rs = RenderingServer::get_singleton(); + + rs->mesh_clear(point_lines_mesh_rid); + rs->mesh_clear(point_handle_mesh_rid); + + if (!obstacle_node->is_visible_in_tree()) { + return; + } - PackedVector2Array poly; - PackedVector3Array polygon_3d_vertices; + Vector<Vector3> edited_vertices; if (wip_active) { - poly = wip; + edited_vertices = wip_vertices; } else { - poly = _get_polygon(); + edited_vertices = obstacle_node->get_vertices(); } - polygon_3d_vertices.resize(poly.size()); - Vector3 *polygon_3d_vertices_ptr = polygon_3d_vertices.ptrw(); - for (int i = 0; i < poly.size(); i++) { - const Vector2 &vert = poly[i]; - polygon_3d_vertices_ptr[i] = Vector3(vert.x, 0.0, vert.y); + if (edited_vertices.is_empty()) { + return; } - point_handle_mesh->clear_surfaces(); - point_lines_mesh->clear_surfaces(); - point_lines_meshinstance->set_material_override(line_material); - point_lines_mesh->surface_begin(Mesh::PRIMITIVE_LINES); + Array point_lines_mesh_array; + point_lines_mesh_array.resize(Mesh::ARRAY_MAX); - Rect2 rect; + Vector<Vector3> point_lines_mesh_vertices; + point_lines_mesh_vertices.resize(edited_vertices.size() * 2); + Vector3 *point_lines_mesh_vertices_ptr = point_lines_mesh_vertices.ptrw(); - for (int i = 0; i < poly.size(); i++) { - Vector2 p, p2; - if (i == edited_point) { - p = edited_point_pos; - } else { - p = poly[i]; - } + int vertex_index = 0; - if ((wip_active && i == poly.size() - 1) || (((i + 1) % poly.size()) == edited_point)) { - p2 = edited_point_pos; + for (int i = 0; i < edited_vertices.size(); i++) { + Vector3 point, next_point; + if (i == edited_point) { + point = edited_point_pos; } else { - p2 = poly[(i + 1) % poly.size()]; + point = edited_vertices[i]; } - if (i == 0) { - rect.position = p; + if ((wip_active && i == edited_vertices.size() - 1) || (((i + 1) % edited_vertices.size()) == edited_point)) { + next_point = edited_point_pos; } else { - rect.expand_to(p); + next_point = edited_vertices[(i + 1) % edited_vertices.size()]; } - Vector3 point = Vector3(p.x, 0.0, p.y); - Vector3 next_point = Vector3(p2.x, 0.0, p2.y); - - point_lines_mesh->surface_set_color(Color(1, 0.3, 0.1, 0.8)); - point_lines_mesh->surface_add_vertex(point); - point_lines_mesh->surface_set_color(Color(1, 0.3, 0.1, 0.8)); - point_lines_mesh->surface_add_vertex(next_point); - - //Color col=Color(1,0.3,0.1,0.8); - //vpc->draw_line(point,next_point,col,2); - //vpc->draw_texture(handle,point-handle->get_size()*0.5); - } - - rect = rect.grow(1); - - AABB r; - r.position.x = rect.position.x; - r.position.y = 0.0; - r.position.z = rect.position.y; - r.size.x = rect.size.x; - r.size.y = 0; - r.size.z = rect.size.y; - - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(0.3, 0, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(0.0, 0.3, 0)); - - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(r.size.x, 0, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(r.size.x, 0, 0) - Vector3(0.3, 0, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(r.size.x, 0, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(r.size.x, 0, 0) + Vector3(0, 0.3, 0)); - - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(0, r.size.y, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(0, r.size.y, 0) - Vector3(0, 0.3, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(0, r.size.y, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + Vector3(0, r.size.y, 0) + Vector3(0.3, 0, 0)); - - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + r.size); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + r.size - Vector3(0.3, 0, 0)); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + r.size); - point_lines_mesh->surface_set_color(Color(0.8, 0.8, 0.8, 0.2)); - point_lines_mesh->surface_add_vertex(r.position + r.size - Vector3(0.0, 0.3, 0)); - - point_lines_mesh->surface_end(); - - if (poly.size() == 0) { - return; + point_lines_mesh_vertices_ptr[vertex_index++] = point; + point_lines_mesh_vertices_ptr[vertex_index++] = next_point; } + point_lines_mesh_array[Mesh::ARRAY_VERTEX] = point_lines_mesh_vertices; + + rs->mesh_add_surface_from_arrays(point_lines_mesh_rid, RS::PRIMITIVE_LINES, point_lines_mesh_array); + rs->instance_set_surface_override_material(point_lines_instance_rid, 0, line_material->get_rid()); + rs->instance_set_transform(point_lines_instance_rid, Transform3D(Basis(), obstacle_node->get_global_position())); + Array point_handle_mesh_array; point_handle_mesh_array.resize(Mesh::ARRAY_MAX); Vector<Vector3> point_handle_mesh_vertices; - point_handle_mesh_vertices.resize(poly.size()); + point_handle_mesh_vertices.resize(edited_vertices.size()); Vector3 *point_handle_mesh_vertices_ptr = point_handle_mesh_vertices.ptrw(); - for (int i = 0; i < poly.size(); i++) { - Vector2 point_2d; - Vector2 p2; + for (int i = 0; i < edited_vertices.size(); i++) { + Vector3 point_handle_3d; if (i == edited_point) { - point_2d = edited_point_pos; + point_handle_3d = edited_point_pos; } else { - point_2d = poly[i]; + point_handle_3d = edited_vertices[i]; } - Vector3 point_handle_3d = Vector3(point_2d.x, 0.0, point_2d.y); point_handle_mesh_vertices_ptr[i] = point_handle_3d; } point_handle_mesh_array[Mesh::ARRAY_VERTEX] = point_handle_mesh_vertices; - point_handle_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_POINTS, point_handle_mesh_array); - point_handle_mesh->surface_set_material(0, handle_material); -} - -void NavigationObstacle3DEditor::edit(Node *p_node) { - obstacle_node = Object::cast_to<NavigationObstacle3D>(p_node); - - if (obstacle_node) { - //Enable the pencil tool if the polygon is empty - if (_get_polygon().is_empty()) { - _menu_option(MODE_CREATE); - } - wip.clear(); - wip_active = false; - edited_point = -1; - if (point_lines_meshinstance->get_parent()) { - point_lines_meshinstance->reparent(p_node, false); - } else { - p_node->add_child(point_lines_meshinstance); - } - _polygon_draw(); - } else { - obstacle_node = nullptr; - - if (point_lines_meshinstance->get_parent()) { - point_lines_meshinstance->get_parent()->remove_child(point_lines_meshinstance); - } - } + rs->mesh_add_surface_from_arrays(point_handle_mesh_rid, RS::PRIMITIVE_POINTS, point_handle_mesh_array); + rs->instance_set_surface_override_material(point_handles_instance_rid, 0, handle_material->get_rid()); + rs->instance_set_transform(point_handles_instance_rid, Transform3D(Basis(), obstacle_node->get_global_position())); } -void NavigationObstacle3DEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_polygon_draw"), &NavigationObstacle3DEditor::_polygon_draw); -} - -NavigationObstacle3DEditor::NavigationObstacle3DEditor() { - obstacle_node = nullptr; +NavigationObstacle3DEditorPlugin *NavigationObstacle3DEditorPlugin::singleton = nullptr; - button_create = memnew(Button); - button_create->set_theme_type_variation("FlatButton"); - add_child(button_create); - button_create->connect(SceneStringName(pressed), callable_mp(this, &NavigationObstacle3DEditor::_menu_option).bind(MODE_CREATE)); - button_create->set_toggle_mode(true); - - button_edit = memnew(Button); - button_edit->set_theme_type_variation("FlatButton"); - add_child(button_edit); - button_edit->connect(SceneStringName(pressed), callable_mp(this, &NavigationObstacle3DEditor::_menu_option).bind(MODE_EDIT)); - button_edit->set_toggle_mode(true); - - mode = MODE_EDIT; - wip_active = false; - point_lines_meshinstance = memnew(MeshInstance3D); - point_lines_mesh.instantiate(); - point_lines_meshinstance->set_mesh(point_lines_mesh); - point_lines_meshinstance->set_transform(Transform3D(Basis(), Vector3(0, 0, 0.00001))); +NavigationObstacle3DEditorPlugin::NavigationObstacle3DEditorPlugin() { + singleton = this; line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - line_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); line_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); line_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); line_material->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); - line_material->set_albedo(Color(1, 1, 1)); + line_material->set_albedo(Color(1, 0.3, 0.1, 0.8)); + line_material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true); handle_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); handle_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - handle_material->set_flag(StandardMaterial3D::FLAG_USE_POINT_SIZE, true); handle_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + handle_material->set_flag(StandardMaterial3D::FLAG_USE_POINT_SIZE, true); handle_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); handle_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); handle_material->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); Ref<Texture2D> handle = EditorNode::get_singleton()->get_editor_theme()->get_icon(SNAME("Editor3DHandle"), EditorStringName(EditorIcons)); handle_material->set_point_size(handle->get_width()); handle_material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, handle); + handle_material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true); - point_handles_meshinstance = memnew(MeshInstance3D); - point_lines_meshinstance->add_child(point_handles_meshinstance); - point_handle_mesh.instantiate(); - point_handles_meshinstance->set_mesh(point_handle_mesh); - point_handles_meshinstance->set_transform(Transform3D(Basis(), Vector3(0, 0, 0.00001))); + RenderingServer *rs = RenderingServer::get_singleton(); - snap_ignore = false; -} + point_lines_mesh_rid = rs->mesh_create(); + point_handle_mesh_rid = rs->mesh_create(); -NavigationObstacle3DEditor::~NavigationObstacle3DEditor() { - memdelete(point_lines_meshinstance); -} + point_lines_instance_rid = rs->instance_create(); + point_handles_instance_rid = rs->instance_create(); -void NavigationObstacle3DEditorPlugin::edit(Object *p_object) { - obstacle_editor->edit(Object::cast_to<Node>(p_object)); -} + rs->instance_set_base(point_lines_instance_rid, point_lines_mesh_rid); + rs->instance_set_base(point_handles_instance_rid, point_handle_mesh_rid); -bool NavigationObstacle3DEditorPlugin::handles(Object *p_object) const { - return Object::cast_to<NavigationObstacle3D>(p_object); -} + obstacle_editor = memnew(HBoxContainer); + obstacle_editor->hide(); -void NavigationObstacle3DEditorPlugin::make_visible(bool p_visible) { - if (p_visible) { - obstacle_editor->show(); - } else { - obstacle_editor->hide(); - obstacle_editor->edit(nullptr); - } -} + Ref<ButtonGroup> bg; + bg.instantiate(); + + button_create = memnew(Button); + button_create->set_theme_type_variation("FlatButton"); + obstacle_editor->add_child(button_create); + button_create->set_tooltip_text(TTR("Add Vertex")); + button_create->connect(SceneStringName(pressed), callable_mp(this, &NavigationObstacle3DEditorPlugin::set_mode).bind(NavigationObstacle3DEditorPlugin::MODE_CREATE)); + button_create->set_toggle_mode(true); + button_create->set_button_group(bg); + + button_edit = memnew(Button); + button_edit->set_theme_type_variation("FlatButton"); + obstacle_editor->add_child(button_edit); + button_edit->connect(SceneStringName(pressed), callable_mp(this, &NavigationObstacle3DEditorPlugin::set_mode).bind(NavigationObstacle3DEditorPlugin::MODE_EDIT)); + button_edit->set_toggle_mode(true); + button_edit->set_button_group(bg); + + button_delete = memnew(Button); + button_delete->set_theme_type_variation("FlatButton"); + obstacle_editor->add_child(button_delete); + button_delete->connect(SceneStringName(pressed), callable_mp(this, &NavigationObstacle3DEditorPlugin::set_mode).bind(NavigationObstacle3DEditorPlugin::MODE_DELETE)); + button_delete->set_toggle_mode(true); + button_delete->set_button_group(bg); + + button_flip = memnew(Button); + button_flip->set_theme_type_variation("FlatButton"); + obstacle_editor->add_child(button_flip); + button_flip->connect(SceneStringName(pressed), callable_mp(this, &NavigationObstacle3DEditorPlugin::set_mode).bind(NavigationObstacle3DEditorPlugin::ACTION_FLIP)); + button_flip->set_toggle_mode(true); + + button_clear = memnew(Button); + button_clear->set_theme_type_variation("FlatButton"); + obstacle_editor->add_child(button_clear); + button_clear->connect(SceneStringName(pressed), callable_mp(this, &NavigationObstacle3DEditorPlugin::set_mode).bind(NavigationObstacle3DEditorPlugin::ACTION_CLEAR)); + button_clear->set_toggle_mode(true); + + button_clear_dialog = memnew(ConfirmationDialog); + button_clear_dialog->set_title(TTR("Please Confirm...")); + button_clear_dialog->set_text(TTR("Remove all vertices?")); + button_clear_dialog->connect(SceneStringName(confirmed), callable_mp(NavigationObstacle3DEditorPlugin::singleton, &NavigationObstacle3DEditorPlugin::action_clear_vertices)); + obstacle_editor->add_child(button_clear_dialog); -NavigationObstacle3DEditorPlugin::NavigationObstacle3DEditorPlugin() { - obstacle_editor = memnew(NavigationObstacle3DEditor); Node3DEditor::get_singleton()->add_control_to_menu_panel(obstacle_editor); - obstacle_editor->hide(); + Ref<NavigationObstacle3DGizmoPlugin> gizmo_plugin = memnew(NavigationObstacle3DGizmoPlugin()); + obstacle_3d_gizmo_plugin = gizmo_plugin; + Node3DEditor::get_singleton()->add_gizmo_plugin(gizmo_plugin); } NavigationObstacle3DEditorPlugin::~NavigationObstacle3DEditorPlugin() { + RenderingServer *rs = RenderingServer::get_singleton(); + ERR_FAIL_NULL(rs); + + if (point_lines_instance_rid.is_valid()) { + rs->free(point_lines_instance_rid); + point_lines_instance_rid = RID(); + } + if (point_lines_mesh_rid.is_valid()) { + rs->free(point_lines_mesh_rid); + point_lines_mesh_rid = RID(); + } + + if (point_handles_instance_rid.is_valid()) { + rs->free(point_handles_instance_rid); + point_handles_instance_rid = RID(); + } + if (point_handle_mesh_rid.is_valid()) { + rs->free(point_handle_mesh_rid); + point_handle_mesh_rid = RID(); + } } diff --git a/editor/plugins/navigation_obstacle_3d_editor_plugin.h b/editor/plugins/navigation_obstacle_3d_editor_plugin.h index c62a5a281b..b6f3a11cf6 100644 --- a/editor/plugins/navigation_obstacle_3d_editor_plugin.h +++ b/editor/plugins/navigation_obstacle_3d_editor_plugin.h @@ -32,79 +32,99 @@ #define NAVIGATION_OBSTACLE_3D_EDITOR_PLUGIN_H #include "editor/plugins/editor_plugin.h" -#include "scene/3d/mesh_instance_3d.h" -#include "scene/3d/physics/collision_polygon_3d.h" +#include "editor/plugins/node_3d_editor_gizmos.h" #include "scene/gui/box_container.h" -#include "scene/resources/immediate_mesh.h" -#include "scene/3d/navigation_obstacle_3d.h" +class Button; +class ConfirmationDialog; +class NavigationObstacle3D; -class CanvasItemEditor; -class MenuButton; +class NavigationObstacle3DGizmoPlugin : public EditorNode3DGizmoPlugin { + GDCLASS(NavigationObstacle3DGizmoPlugin, EditorNode3DGizmoPlugin); -class NavigationObstacle3DEditor : public HBoxContainer { - GDCLASS(NavigationObstacle3DEditor, HBoxContainer); +public: + virtual bool has_gizmo(Node3D *p_spatial) override; + virtual String get_gizmo_name() const override; - enum Mode { - MODE_CREATE, - MODE_EDIT, + virtual void redraw(EditorNode3DGizmo *p_gizmo) override; - }; + bool can_be_hidden() const override; + int get_priority() const override; - Mode mode; + virtual int subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const override; + virtual Vector<int> subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const override; + virtual Transform3D get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const override; + virtual void set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) override; + virtual void commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel = false) override; - Button *button_create = nullptr; - Button *button_edit = nullptr; + NavigationObstacle3DGizmoPlugin(); +}; + +class NavigationObstacle3DEditorPlugin : public EditorPlugin { + GDCLASS(NavigationObstacle3DEditorPlugin, EditorPlugin); + + Ref<NavigationObstacle3DGizmoPlugin> obstacle_3d_gizmo_plugin; + + NavigationObstacle3D *obstacle_node = nullptr; Ref<StandardMaterial3D> line_material; Ref<StandardMaterial3D> handle_material; - Panel *panel = nullptr; - NavigationObstacle3D *obstacle_node = nullptr; - Ref<ImmediateMesh> point_lines_mesh; - MeshInstance3D *point_lines_meshinstance = nullptr; - MeshInstance3D *point_handles_meshinstance = nullptr; - Ref<ArrayMesh> point_handle_mesh; + RID point_lines_mesh_rid; + RID point_lines_instance_rid; + RID point_handle_mesh_rid; + RID point_handles_instance_rid; - MenuButton *options = nullptr; +public: + enum Mode { + MODE_CREATE = 0, + MODE_EDIT, + MODE_DELETE, + ACTION_FLIP, + ACTION_CLEAR, + }; - int edited_point = 0; - Vector2 edited_point_pos; - PackedVector2Array pre_move_edit; - PackedVector2Array wip; - bool wip_active; - bool snap_ignore; +private: + int mode = MODE_EDIT; - float prev_depth = 0.0f; + int edited_point = 0; + Vector3 edited_point_pos; + Vector<Vector3> pre_move_edit; + Vector<Vector3> wip_vertices; + bool wip_active = false; + bool snap_ignore = false; void _wip_close(); - void _polygon_draw(); - void _menu_option(int p_option); + void _wip_cancel(); + void _update_theme(); + + Button *button_create = nullptr; + Button *button_edit = nullptr; + Button *button_delete = nullptr; + Button *button_flip = nullptr; + Button *button_clear = nullptr; - PackedVector2Array _get_polygon(); - void _set_polygon(const PackedVector2Array &p_poly); + ConfirmationDialog *button_clear_dialog = nullptr; protected: void _notification(int p_what); void _node_removed(Node *p_node); - static void _bind_methods(); public: - virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event); - void edit(Node *p_node); - NavigationObstacle3DEditor(); - ~NavigationObstacle3DEditor(); -}; + HBoxContainer *obstacle_editor = nullptr; + static NavigationObstacle3DEditorPlugin *singleton; -class NavigationObstacle3DEditorPlugin : public EditorPlugin { - GDCLASS(NavigationObstacle3DEditorPlugin, EditorPlugin); + void redraw(); - NavigationObstacle3DEditor *obstacle_editor = nullptr; + void set_mode(int p_mode); + int get_mode() { return mode; } -public: - virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return obstacle_editor->forward_3d_gui_input(p_camera, p_event); } + void action_flip_vertices(); + void action_clear_vertices(); + + virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override; - virtual String get_name() const override { return "NavigationObstacle3DEditor"; } + virtual String get_name() const override { return "NavigationObstacle3D"; } bool has_main_screen() const override { return false; } virtual void edit(Object *p_object) override; virtual bool handles(Object *p_object) const override; diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp index 3c71040408..c11a7cf20e 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.cpp +++ b/editor/plugins/navigation_polygon_editor_plugin.cpp @@ -38,8 +38,8 @@ Ref<NavigationPolygon> NavigationPolygonEditor::_ensure_navpoly() const { Ref<NavigationPolygon> navpoly = node->get_navigation_polygon(); - if (!navpoly.is_valid()) { - navpoly = Ref<NavigationPolygon>(memnew(NavigationPolygon)); + if (navpoly.is_null()) { + navpoly.instantiate(); node->set_navigation_polygon(navpoly); } return navpoly; diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 5afe01025d..810d1674ca 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -7050,12 +7050,12 @@ void fragment() { col.a = EDITOR_GET("editors/3d/manipulator_gizmo_opacity"); - move_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); - move_plane_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); - rotate_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); - scale_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); - scale_plane_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); - axis_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); + move_gizmo[i].instantiate(); + move_plane_gizmo[i].instantiate(); + rotate_gizmo[i].instantiate(); + scale_gizmo[i].instantiate(); + scale_plane_gizmo[i].instantiate(); + axis_gizmo[i].instantiate(); Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D); mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); @@ -7286,7 +7286,7 @@ void fragment() { border_mat->set_shader(border_shader); border_mat->set_shader_parameter("albedo", Color(0.75, 0.75, 0.75, col.a / 3.0)); - rotate_gizmo[3] = Ref<ArrayMesh>(memnew(ArrayMesh)); + rotate_gizmo[3].instantiate(); rotate_gizmo[3]->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arrays); rotate_gizmo[3]->surface_set_material(0, border_mat); } @@ -8639,7 +8639,7 @@ Node3DEditor::Node3DEditor() { gizmo.visible = true; gizmo.scale = 1.0; - viewport_environment = Ref<Environment>(memnew(Environment)); + viewport_environment.instantiate(); VBoxContainer *vbc = this; custom_camera = nullptr; diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp index 91cff9f8e2..3a4b3a0ea2 100644 --- a/editor/plugins/path_3d_editor_plugin.cpp +++ b/editor/plugins/path_3d_editor_plugin.cpp @@ -922,7 +922,7 @@ Ref<EditorNode3DGizmo> Path3DGizmoPlugin::create_gizmo(Node3D *p_spatial) { Path3D *path = Object::cast_to<Path3D>(p_spatial); if (path) { - ref = Ref<Path3DGizmo>(memnew(Path3DGizmo(path, disk_size))); + ref.instantiate(path, disk_size); } return ref; diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index 6cd04174a5..8ab08ff28f 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -275,7 +275,11 @@ void Polygon2DEditor::_uv_edit_mode_select(int p_mode) { uv_button[UV_MODE_REMOVE_POLYGON]->hide(); uv_button[UV_MODE_PAINT_WEIGHT]->hide(); uv_button[UV_MODE_CLEAR_WEIGHT]->hide(); - _uv_mode(UV_MODE_EDIT_POINT); + if (node->get_polygon().is_empty()) { + _uv_mode(UV_MODE_CREATE); + } else { + _uv_mode(UV_MODE_EDIT_POINT); + } bone_scroll_main_vb->hide(); bone_paint_strength->hide(); @@ -317,9 +321,16 @@ void Polygon2DEditor::_uv_edit_mode_select(int p_mode) { uv_edit_draw->queue_redraw(); } +void Polygon2DEditor::_uv_edit_popup_show() { + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->connect("version_changed", callable_mp(this, &Polygon2DEditor::_update_available_modes)); +} + void Polygon2DEditor::_uv_edit_popup_hide() { EditorSettings::get_singleton()->set_project_metadata("dialog_bounds", "uv_editor", Rect2(uv_edit->get_position(), uv_edit->get_size())); _cancel_editing(); + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->disconnect("version_changed", callable_mp(this, &Polygon2DEditor::_update_available_modes)); } void Polygon2DEditor::_menu_option(int p_option) { @@ -346,6 +357,7 @@ void Polygon2DEditor::_menu_option(int p_option) { uv_edit->popup_centered_ratio(0.85); } _update_bone_list(); + _update_available_modes(); get_tree()->connect("process_frame", callable_mp(this, &Polygon2DEditor::_center_view), CONNECT_ONE_SHOT); } break; case UVEDIT_POLYGON_TO_UV: { @@ -408,6 +420,7 @@ void Polygon2DEditor::_cancel_editing() { node->set_polygons(polygons_prev); _update_polygon_editing_state(); + _update_available_modes(); } else if (uv_drag) { uv_drag = false; if (uv_edit_mode[0]->is_pressed()) { // Edit UV. @@ -566,6 +579,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { uv_drag = false; uv_create = false; + _update_available_modes(); _uv_mode(UV_MODE_EDIT_POINT); _menu_option(MODE_EDIT); } else { @@ -973,6 +987,23 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { } } +void Polygon2DEditor::_update_available_modes() { + // Force point editing mode if there's no polygon yet. + if (node->get_polygon().is_empty()) { + if (!uv_edit_mode[1]->is_pressed()) { + uv_edit_mode[1]->set_pressed(true); + _uv_edit_mode_select(1); + } + uv_edit_mode[0]->set_disabled(true); + uv_edit_mode[2]->set_disabled(true); + uv_edit_mode[3]->set_disabled(true); + } else { + uv_edit_mode[0]->set_disabled(false); + uv_edit_mode[2]->set_disabled(false); + uv_edit_mode[3]->set_disabled(false); + } +} + void Polygon2DEditor::_center_view() { Size2 texture_size; if (node->get_texture().is_valid()) { @@ -1324,6 +1355,7 @@ Polygon2DEditor::Polygon2DEditor() { add_child(uv_edit); uv_edit->connect(SceneStringName(confirmed), callable_mp(this, &Polygon2DEditor::_uv_edit_popup_hide)); uv_edit->connect("canceled", callable_mp(this, &Polygon2DEditor::_uv_edit_popup_hide)); + uv_edit->connect("about_to_popup", callable_mp(this, &Polygon2DEditor::_uv_edit_popup_show)); VBoxContainer *uv_main_vb = memnew(VBoxContainer); uv_edit->add_child(uv_main_vb); diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h index cb082ec513..4e1cd7172e 100644 --- a/editor/plugins/polygon_2d_editor_plugin.h +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -142,6 +142,7 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { void _cancel_editing(); void _update_polygon_editing_state(); + void _update_available_modes(); void _center_view(); void _update_zoom_and_pan(bool p_zoom_at_center); @@ -157,6 +158,7 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { void _set_snap_step_y(real_t p_val); void _uv_edit_mode_select(int p_mode); + void _uv_edit_popup_show(); void _uv_edit_popup_hide(); void _bone_paint_selected(int p_index); diff --git a/editor/plugins/polygon_3d_editor_plugin.cpp b/editor/plugins/polygon_3d_editor_plugin.cpp index 9bb2d81549..017504f0d6 100644 --- a/editor/plugins/polygon_3d_editor_plugin.cpp +++ b/editor/plugins/polygon_3d_editor_plugin.cpp @@ -554,7 +554,7 @@ Polygon3DEditor::Polygon3DEditor() { imgeom->set_mesh(imesh); imgeom->set_transform(Transform3D(Basis(), Vector3(0, 0, 0.00001))); - line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + line_material.instantiate(); line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); line_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); line_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); @@ -562,7 +562,7 @@ Polygon3DEditor::Polygon3DEditor() { line_material->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); line_material->set_albedo(Color(1, 1, 1)); - handle_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + handle_material.instantiate(); handle_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); handle_material->set_flag(StandardMaterial3D::FLAG_USE_POINT_SIZE, true); handle_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 2edc096382..8c3979918d 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -2185,8 +2185,6 @@ void ScriptEditor::_update_script_colors() { continue; } - script_list->set_item_custom_bg_color(i, Color(0, 0, 0, 0)); - if (script_temperature_enabled) { int pass = n->get_meta("__editor_pass", -1); if (pass < 0) { @@ -2212,7 +2210,7 @@ void ScriptEditor::_update_script_names() { HashSet<Ref<Script>> used; Node *edited = EditorNode::get_singleton()->get_edited_scene(); - if (edited) { + if (edited && EDITOR_GET("text_editor/script_list/highlight_scene_scripts")) { _find_scripts(edited, edited, used); } @@ -2382,7 +2380,7 @@ void ScriptEditor::_update_script_names() { script_list->set_item_tooltip(index, sedata_filtered[i].tooltip); script_list->set_item_metadata(index, sedata_filtered[i].index); /* Saving as metadata the script's index in the tab container and not the filtered one */ if (sedata_filtered[i].used) { - script_list->set_item_custom_bg_color(index, Color(88 / 255.0, 88 / 255.0, 60 / 255.0)); + script_list->set_item_custom_bg_color(index, Color(.5, .5, .5, .125)); } if (tab_container->get_current_tab() == sedata_filtered[i].index) { script_list->select(index); diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 19fbd2dd3b..369a1fc864 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -1186,8 +1186,8 @@ Skeleton3DEditor::Skeleton3DEditor(EditorInspectorPluginSkeleton *e_plugin, Skel singleton = this; // Handle. - handle_material = Ref<ShaderMaterial>(memnew(ShaderMaterial)); - handle_shader = Ref<Shader>(memnew(Shader)); + handle_material.instantiate(); + handle_shader.instantiate(); handle_shader->set_code(R"( // Skeleton 3D gizmo handle shader. diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index 34e24c1424..941d44c85e 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -1699,7 +1699,7 @@ void TileSetAtlasSourceEditor::_menu_option(int p_option) { void TileSetAtlasSourceEditor::shortcut_input(const Ref<InputEvent> &p_event) { // Check for shortcuts. - if (ED_IS_SHORTCUT("tiles_editor/delete_tile", p_event)) { + if (ED_IS_SHORTCUT("tiles_editor/delete", p_event)) { if (tools_button_group->get_pressed_button() == tool_select_button && !selection.is_empty()) { _menu_option(TILE_DELETE); accept_event(); @@ -2711,7 +2711,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { tile_atlas_control_unscaled->set_mouse_filter(Control::MOUSE_FILTER_IGNORE); alternative_tile_popup_menu = memnew(PopupMenu); - alternative_tile_popup_menu->add_shortcut(ED_SHORTCUT("tiles_editor/delete_tile", TTR("Delete"), Key::KEY_DELETE), TILE_DELETE); + alternative_tile_popup_menu->add_shortcut(ED_GET_SHORTCUT("tiles_editor/delete"), TILE_DELETE); alternative_tile_popup_menu->connect(SceneStringName(id_pressed), callable_mp(this, &TileSetAtlasSourceEditor::_menu_option)); tile_atlas_view->add_child(alternative_tile_popup_menu); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 9c1befa144..ec0edc0c96 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -1985,6 +1985,67 @@ bool VisualShaderEditor::_update_preview_parameter_tree() { return found; } +void VisualShaderEditor::_preview_tools_menu_option(int p_idx) { + ShaderMaterial *src_mat = nullptr; + + if (p_idx == COPY_PARAMS_FROM_MATERIAL || p_idx == PASTE_PARAMS_TO_MATERIAL) { + for (int i = EditorNode::get_singleton()->get_editor_selection_history()->get_path_size() - 1; i >= 0; i--) { + Object *object = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_selection_history()->get_path_object(i)); + ShaderMaterial *src_mat2; + if (!object) { + continue; + } + if (object->has_method("get_material_override")) { // Trying to get material from MeshInstance. + src_mat2 = Object::cast_to<ShaderMaterial>(object->call("get_material_override")); + } else if (object->has_method("get_material")) { // From CanvasItem/Node2D. + src_mat2 = Object::cast_to<ShaderMaterial>(object->call("get_material")); + } else { + src_mat2 = Object::cast_to<ShaderMaterial>(object); + } + + if (src_mat2 && src_mat2->get_shader().is_valid() && src_mat2->get_shader() == visual_shader) { + src_mat = src_mat2; + break; + } + } + } + + switch (p_idx) { + case COPY_PARAMS_FROM_MATERIAL: + if (src_mat) { + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Copy Preview Shader Parameters From Material")); + + List<PropertyInfo> params; + preview_material->get_shader()->get_shader_uniform_list(¶ms); + for (const PropertyInfo &E : params) { + undo_redo->add_do_method(visual_shader.ptr(), "_set_preview_shader_parameter", E.name, src_mat->get_shader_parameter(E.name)); + undo_redo->add_undo_method(visual_shader.ptr(), "_set_preview_shader_parameter", E.name, preview_material->get_shader_parameter(E.name)); + } + + undo_redo->commit_action(); + } + break; + case PASTE_PARAMS_TO_MATERIAL: + if (src_mat) { + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Paste Preview Shader Parameters To Material")); + + List<PropertyInfo> params; + preview_material->get_shader()->get_shader_uniform_list(¶ms); + for (const PropertyInfo &E : params) { + undo_redo->add_do_method(src_mat, "set_shader_parameter", E.name, preview_material->get_shader_parameter(E.name)); + undo_redo->add_undo_method(src_mat, "set_shader_parameter", E.name, src_mat->get_shader_parameter(E.name)); + } + + undo_redo->commit_action(); + } + break; + default: + break; + } +} + void VisualShaderEditor::_clear_preview_param() { selected_param_id = ""; current_prop = nullptr; @@ -5159,6 +5220,7 @@ void VisualShaderEditor::_notification(int p_what) { } tools->set_button_icon(get_editor_theme_icon(SNAME("Tools"))); + preview_tools->set_button_icon(get_editor_theme_icon(SNAME("Tools"))); if (is_visible_in_tree()) { _update_graph(); @@ -6555,11 +6617,21 @@ VisualShaderEditor::VisualShaderEditor() { VBoxContainer *params_vbox = memnew(VBoxContainer); preview_split->add_child(params_vbox); + HBoxContainer *filter_hbox = memnew(HBoxContainer); + params_vbox->add_child(filter_hbox); + param_filter = memnew(LineEdit); + filter_hbox->add_child(param_filter); param_filter->connect(SceneStringName(text_changed), callable_mp(this, &VisualShaderEditor::_param_filter_changed)); param_filter->set_h_size_flags(SIZE_EXPAND_FILL); param_filter->set_placeholder(TTR("Filter Parameters")); - params_vbox->add_child(param_filter); + + preview_tools = memnew(MenuButton); + filter_hbox->add_child(preview_tools); + preview_tools->set_tooltip_text(TTR("Options")); + preview_tools->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &VisualShaderEditor::_preview_tools_menu_option)); + preview_tools->get_popup()->add_item(TTR("Copy Parameters From Material"), COPY_PARAMS_FROM_MATERIAL); + preview_tools->get_popup()->add_item(TTR("Paste Parameters To Material"), PASTE_PARAMS_TO_MATERIAL); ScrollContainer *sc = memnew(ScrollContainer); sc->set_v_size_flags(SIZE_EXPAND_FILL); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index d3dc2e7564..a8655b8141 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -276,6 +276,7 @@ class VisualShaderEditor : public ShaderEditor { bool shader_preview_showed = true; LineEdit *param_filter = nullptr; + MenuButton *preview_tools = nullptr; String selected_param_id; Tree *parameters = nullptr; HashMap<String, PropertyInfo> parameter_props; @@ -318,6 +319,11 @@ class VisualShaderEditor : public ShaderEditor { COLLAPSE_ALL }; + enum PreviewToolsMenuOptions { + COPY_PARAMS_FROM_MATERIAL, + PASTE_PARAMS_TO_MATERIAL, + }; + #ifdef MINGW_ENABLED #undef DELETE #endif @@ -367,6 +373,7 @@ class VisualShaderEditor : public ShaderEditor { void _show_add_varying_dialog(); void _show_remove_varying_dialog(); + void _preview_tools_menu_option(int p_idx); void _clear_preview_param(); void _update_preview_parameter_list(); bool _update_preview_parameter_tree(); diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 89c18143dc..97f1d5d641 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -31,6 +31,7 @@ #include "project_settings_editor.h" #include "core/config/project_settings.h" +#include "core/input/input_map.h" #include "editor/editor_inspector.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" @@ -390,7 +391,7 @@ void ProjectSettingsEditor::_action_added(const String &p_name) { Dictionary action; action["events"] = Array(); - action["deadzone"] = 0.2f; + action["deadzone"] = InputMap::DEFAULT_DEADZONE; EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); undo_redo->create_action(TTR("Add Input Action")); diff --git a/editor/register_editor_types.cpp b/editor/register_editor_types.cpp index c4ebca7308..2d3cbfb1e3 100644 --- a/editor/register_editor_types.cpp +++ b/editor/register_editor_types.cpp @@ -52,6 +52,7 @@ #include "editor/filesystem_dock.h" #include "editor/gui/editor_file_dialog.h" #include "editor/gui/editor_spin_slider.h" +#include "editor/gui/editor_toaster.h" #include "editor/import/3d/resource_importer_obj.h" #include "editor/import/3d/resource_importer_scene.h" #include "editor/import/editor_import_plugin.h" @@ -146,6 +147,7 @@ void register_editor_types() { GDREGISTER_CLASS(EditorSelection); GDREGISTER_CLASS(EditorFileDialog); GDREGISTER_CLASS(EditorSettings); + GDREGISTER_ABSTRACT_CLASS(EditorToaster); GDREGISTER_CLASS(EditorNode3DGizmo); GDREGISTER_CLASS(EditorNode3DGizmoPlugin); GDREGISTER_ABSTRACT_CLASS(EditorResourcePreview); diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 8dd2fe8e4e..d38ff7af76 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -359,6 +359,7 @@ void ScriptCreateDialog::_create_new() { alert->popup_centered(); return; } + EditorNode::get_singleton()->ensure_uid_file(lpath); } emit_signal(SNAME("script_created"), scr); diff --git a/editor/shader_create_dialog.cpp b/editor/shader_create_dialog.cpp index 2bfe088e7f..e1c797633a 100644 --- a/editor/shader_create_dialog.cpp +++ b/editor/shader_create_dialog.cpp @@ -31,6 +31,7 @@ #include "shader_create_dialog.h" #include "core/config/project_settings.h" +#include "editor/editor_node.h" #include "editor/gui/editor_file_dialog.h" #include "editor/gui/editor_validation_panel.h" #include "editor/themes/editor_scale.h" @@ -240,6 +241,7 @@ void fog() { alert->popup_centered(); return; } + EditorNode::get_singleton()->ensure_uid_file(lpath); emit_signal(SNAME("shader_include_created"), shader_inc); } else { @@ -258,6 +260,7 @@ void fog() { alert->popup_centered(); return; } + EditorNode::get_singleton()->ensure_uid_file(lpath); } emit_signal(SNAME("shader_created"), shader); diff --git a/main/main.cpp b/main/main.cpp index fb21ee502f..0a905f16ca 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -653,7 +653,7 @@ void Main::print_help(const char *p_binary) { print_help_option("--delta-smoothing <enable>", "Enable or disable frame delta smoothing [\"enable\", \"disable\"].\n"); print_help_option("--print-fps", "Print the frames per second to the stdout.\n"); #ifdef TOOLS_ENABLED - print_help_option("--editor-pseudolocalization", "Enable pseudolocalization for the editor and the project manager.\n"); + print_help_option("--editor-pseudolocalization", "Enable pseudolocalization for the editor and the project manager.\n", CLI_OPTION_AVAILABILITY_EDITOR); #endif print_help_title("Standalone tools"); @@ -2554,7 +2554,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph Engine::get_singleton()->set_physics_ticks_per_second(GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "physics/common/physics_ticks_per_second", PROPERTY_HINT_RANGE, "1,1000,1"), 60)); Engine::get_singleton()->set_max_physics_steps_per_frame(GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "physics/common/max_physics_steps_per_frame", PROPERTY_HINT_RANGE, "1,100,1"), 8)); Engine::get_singleton()->set_physics_jitter_fix(GLOBAL_DEF("physics/common/physics_jitter_fix", 0.5)); - Engine::get_singleton()->set_max_fps(GLOBAL_DEF(PropertyInfo(Variant::INT, "application/run/max_fps", PROPERTY_HINT_RANGE, "0,1000,1"), 0)); GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "audio/driver/output_latency", PROPERTY_HINT_RANGE, "1,100,1"), 15); // Use a safer default output_latency for web to avoid audio cracking on low-end devices, especially mobile. @@ -2575,10 +2574,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->set_environment("MVK_CONFIG_LOG_LEVEL", OS::get_singleton()->_verbose_stdout ? "3" : "1"); // 1 = Errors only, 3 = Info #endif - if (max_fps >= 0) { - Engine::get_singleton()->set_max_fps(max_fps); - } - if (frame_delay == 0) { frame_delay = GLOBAL_DEF(PropertyInfo(Variant::INT, "application/run/frame_delay_msec", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), 0); if (Engine::get_singleton()->is_editor_hint()) { @@ -3024,6 +3019,13 @@ Error Main::setup2(bool p_show_boot_logo) { OS::get_singleton()->benchmark_end_measure("Servers", "Display"); } + // Max FPS needs to be set after the DisplayServer is created. + Engine::get_singleton()->set_max_fps(GLOBAL_DEF(PropertyInfo(Variant::INT, "application/run/max_fps", PROPERTY_HINT_RANGE, "0,1000,1"), 0)); + + if (max_fps >= 0) { + Engine::get_singleton()->set_max_fps(max_fps); + } + #ifdef TOOLS_ENABLED // If the editor is running in windowed mode, ensure the window rect fits // the screen in case screen count or position has changed. @@ -4040,12 +4042,12 @@ int Main::start() { EditorNode *editor_node = nullptr; if (editor) { OS::get_singleton()->benchmark_begin_measure("Startup", "Editor"); - editor_node = memnew(EditorNode); if (editor_pseudolocalization) { translation_server->get_editor_domain()->set_pseudolocalization_enabled(true); } + editor_node = memnew(EditorNode); sml->get_root()->add_child(editor_node); if (!_export_preset.is_empty()) { @@ -4237,14 +4239,15 @@ int Main::start() { if (project_manager) { OS::get_singleton()->benchmark_begin_measure("Startup", "Project Manager"); Engine::get_singleton()->set_editor_hint(true); - ProjectManager *pmanager = memnew(ProjectManager); - ProgressDialog *progress_dialog = memnew(ProgressDialog); - pmanager->add_child(progress_dialog); if (editor_pseudolocalization) { translation_server->get_editor_domain()->set_pseudolocalization_enabled(true); } + ProjectManager *pmanager = memnew(ProjectManager); + ProgressDialog *progress_dialog = memnew(ProgressDialog); + pmanager->add_child(progress_dialog); + sml->get_root()->add_child(pmanager); OS::get_singleton()->benchmark_end_measure("Startup", "Project Manager"); } diff --git a/methods.py b/methods.py index 64c3839718..d89185f585 100644 --- a/methods.py +++ b/methods.py @@ -409,8 +409,7 @@ def use_windows_spawn_fix(self, platform=None): "shell": False, "env": env, } - if sys.version_info >= (3, 7, 0): - popen_args["text"] = True + popen_args["text"] = True proc = subprocess.Popen(cmdline, **popen_args) _, err = proc.communicate() rv = proc.wait() @@ -593,23 +592,6 @@ def glob_recursive(pattern, node="."): return results -def add_to_vs_project(env, sources): - for x in sources: - fname = env.File(x).path if isinstance(x, str) else env.File(x)[0].path - pieces = fname.split(".") - if len(pieces) > 0: - basename = pieces[0] - basename = basename.replace("\\\\", "/") - if os.path.isfile(basename + ".h"): - env.vs_incs += [basename + ".h"] - elif os.path.isfile(basename + ".hpp"): - env.vs_incs += [basename + ".hpp"] - if os.path.isfile(basename + ".c"): - env.vs_srcs += [basename + ".c"] - elif os.path.isfile(basename + ".cpp"): - env.vs_srcs += [basename + ".cpp"] - - def precious_program(env, program, sources, **args): program = env.ProgramOriginal(program, sources, **args) env.Precious(program) @@ -1112,9 +1094,7 @@ def generate_vs_project(env, original_args, project_name="godot"): import json md5 = hashlib.md5( - json.dumps(headers + headers_dirs + sources + sources_dirs + others + others_dirs, sort_keys=True).encode( - "utf-8" - ) + json.dumps(sorted(headers + headers_dirs + sources + sources_dirs + others + others_dirs)).encode("utf-8") ).hexdigest() if os.path.exists(f"{project_name}.vcxproj.filters"): diff --git a/misc/dist/html/full-size.html b/misc/dist/html/full-size.html index 352046df30..b59c417d36 100644 --- a/misc/dist/html/full-size.html +++ b/misc/dist/html/full-size.html @@ -38,7 +38,7 @@ body { } #status { - background-color: #242424; + background-color: $GODOT_SPLASH_COLOR; display: flex; flex-direction: column; justify-content: center; diff --git a/misc/dist/linux/org.godotengine.Godot.appdata.xml b/misc/dist/linux/org.godotengine.Godot.appdata.xml index af647bc866..8b27b6300d 100644 --- a/misc/dist/linux/org.godotengine.Godot.appdata.xml +++ b/misc/dist/linux/org.godotengine.Godot.appdata.xml @@ -6,7 +6,7 @@ <project_license>MIT</project_license> <name>Godot Engine</name> <summary>Multi-platform 2D and 3D game engine with a feature-rich editor</summary> - <launchable type="desktop-id">org.godotengine.Godot.desktop</launchable> + <launchable type="desktop-id">org.godotengine.Godot.desktop</launchable> <description> <p> Godot is an advanced, feature-packed, multi-platform 2D and 3D game diff --git a/misc/extension_api_validation/4.3-stable.expected b/misc/extension_api_validation/4.3-stable.expected index 3770664115..75e81b5ff4 100644 --- a/misc/extension_api_validation/4.3-stable.expected +++ b/misc/extension_api_validation/4.3-stable.expected @@ -108,3 +108,17 @@ GH-97257 Validate extension JSON: Error: Field 'classes/EditorFeatureProfile/enums/Feature/values/FEATURE_MAX': value changed value in new API, from 8.0 to 9. New entry to the `EditorFeatureProfile.Feature` enum added. Those need to go before `FEATURE_MAX`, which will always cause a compatibility break. + + +GH-91201 +-------- +Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/OS/methods/read_string_from_stdin': arguments + +Added optional argument. Compatibility method registered. + + +GH-98918 +-------- +Validate extension JSON: Error: Field 'classes/FileAccess/methods/open_encrypted/arguments': size changed value in new API, from 3 to 4. + +Optional argument added to allow setting initialization vector. Compatibility method registered. diff --git a/modules/enet/enet_connection.cpp b/modules/enet/enet_connection.cpp index 2ccfd5d326..9c9302a51c 100644 --- a/modules/enet/enet_connection.cpp +++ b/modules/enet/enet_connection.cpp @@ -113,7 +113,7 @@ Ref<ENetPacketPeer> ENetConnection::connect_to_host(const String &p_address, int if (peer == nullptr) { return nullptr; } - out = Ref<ENetPacketPeer>(memnew(ENetPacketPeer(peer))); + out.instantiate(peer); peers.push_back(out); return out; } diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index ede4ce6617..0355119442 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -666,7 +666,19 @@ @export var car_label = "Speedy" @export var car_number = 3 [/codeblock] - [b]Note:[/b] Subgroups cannot be nested, they only provide one extra level of depth. Just like the next group ends the previous group, so do the subsequent subgroups. + [b]Note:[/b] Subgroups cannot be nested, but you can use the slash separator ([code]/[/code]) to achieve the desired effect: + [codeblock] + @export_group("Car Properties") + @export_subgroup("Wheels", "wheel_") + @export_subgroup("Wheels/Front", "front_wheel_") + @export var front_wheel_strength = 10 + @export var front_wheel_mobility = 5 + @export_subgroup("Wheels/Rear", "rear_wheel_") + @export var rear_wheel_strength = 8 + @export var rear_wheel_mobility = 3 + @export_subgroup("Wheels", "wheel_") + @export var wheel_material: PhysicsMaterial + [/codeblock] </description> </annotation> <annotation name="@export_tool_button"> diff --git a/modules/gdscript/doc_classes/GDScript.xml b/modules/gdscript/doc_classes/GDScript.xml index 5f7a7e2915..c3fa59dc23 100644 --- a/modules/gdscript/doc_classes/GDScript.xml +++ b/modules/gdscript/doc_classes/GDScript.xml @@ -16,11 +16,10 @@ <return type="Variant" /> <description> Returns a new instance of the script. - For example: [codeblock] var MyClass = load("myclass.gd") var instance = MyClass.new() - assert(instance.get_script() == MyClass) + print(instance.get_script() == MyClass) # Prints true [/codeblock] </description> </method> diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 951ae6ce99..a29bd1fdb5 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -43,6 +43,7 @@ #include "core/config/engine.h" #include "core/core_constants.h" #include "core/io/file_access.h" +#include "core/math/expression.h" #ifdef TOOLS_ENABLED #include "core/config/project_settings.h" @@ -427,7 +428,30 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> } String GDScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) { - return ""; + List<String> names; + List<Variant> values; + debug_get_stack_level_locals(p_level, &names, &values, p_max_subitems, p_max_depth); + + Vector<String> name_vector; + for (const String &name : names) { + name_vector.push_back(name); + } + + Array value_array; + for (const Variant &value : values) { + value_array.push_back(value); + } + + Expression expression; + if (expression.parse(p_expression, name_vector) == OK) { + ScriptInstance *instance = debug_get_stack_level_instance(p_level); + if (instance) { + Variant return_val = expression.execute(value_array, instance->get_owner()); + return return_val.get_construct_string(); + } + } + + return String(); } void GDScriptLanguage::get_recognized_extensions(List<String> *p_extensions) const { diff --git a/modules/gltf/doc_classes/GLTFAccessor.xml b/modules/gltf/doc_classes/GLTFAccessor.xml index 04fa2a9835..271f098803 100644 --- a/modules/gltf/doc_classes/GLTFAccessor.xml +++ b/modules/gltf/doc_classes/GLTFAccessor.xml @@ -102,13 +102,13 @@ Component type "UNSIGNED_INT". The value is [code]0x1405[/code] which comes from OpenGL. This indicates data is stored in 4-byte or 32-bit unsigned integers. This is a core part of the glTF specification. </constant> <constant name="COMPONENT_TYPE_SINGLE_FLOAT" value="5126" enum="GLTFComponentType"> - Component type "FLOAT". The value is [code]0x1406[/code] which comes from OpenGL. This indicates data is stored in 4-byte or 32-bit floating point numbers. This is a core part of the glTF specification. + Component type "FLOAT". The value is [code]0x1406[/code] which comes from OpenGL. This indicates data is stored in 4-byte or 32-bit floating-point numbers. This is a core part of the glTF specification. </constant> <constant name="COMPONENT_TYPE_DOUBLE_FLOAT" value="5130" enum="GLTFComponentType"> - Component type "DOUBLE". The value is [code]0x140A[/code] which comes from OpenGL. This indicates data is stored in 8-byte or 64-bit floating point numbers. This is NOT a core part of the glTF specification, and may not be supported by all glTF importers. May be used by some extensions including [code]KHR_interactivity[/code]. + Component type "DOUBLE". The value is [code]0x140A[/code] which comes from OpenGL. This indicates data is stored in 8-byte or 64-bit floating-point numbers. This is NOT a core part of the glTF specification, and may not be supported by all glTF importers. May be used by some extensions including [code]KHR_interactivity[/code]. </constant> <constant name="COMPONENT_TYPE_HALF_FLOAT" value="5131" enum="GLTFComponentType"> - Component type "HALF_FLOAT". The value is [code]0x140B[/code] which comes from OpenGL. This indicates data is stored in 2-byte or 16-bit floating point numbers. This is NOT a core part of the glTF specification, and may not be supported by all glTF importers. May be used by some extensions including [code]KHR_interactivity[/code]. + Component type "HALF_FLOAT". The value is [code]0x140B[/code] which comes from OpenGL. This indicates data is stored in 2-byte or 16-bit floating-point numbers. This is NOT a core part of the glTF specification, and may not be supported by all glTF importers. May be used by some extensions including [code]KHR_interactivity[/code]. </constant> <constant name="COMPONENT_TYPE_SIGNED_LONG" value="5134" enum="GLTFComponentType"> Component type "LONG". The value is [code]0x140E[/code] which comes from OpenGL. This indicates data is stored in 8-byte or 64-bit signed integers. This is NOT a core part of the glTF specification, and may not be supported by all glTF importers. May be used by some extensions including [code]KHR_interactivity[/code]. diff --git a/modules/gltf/doc_classes/GLTFState.xml b/modules/gltf/doc_classes/GLTFState.xml index 376c3c89f5..c81c2f09f0 100644 --- a/modules/gltf/doc_classes/GLTFState.xml +++ b/modules/gltf/doc_classes/GLTFState.xml @@ -306,7 +306,7 @@ The binary buffer attached to a .glb file. </member> <member name="import_as_skeleton_bones" type="bool" setter="set_import_as_skeleton_bones" getter="get_import_as_skeleton_bones" default="false"> - True to force all GLTFNodes in the document to be bones of a single Skeleton3D godot node. + If [code]true[/code], forces all GLTFNodes in the document to be bones of a single [Skeleton3D] Godot node. </member> <member name="json" type="Dictionary" setter="set_json" getter="get_json" default="{}"> The original raw JSON document corresponding to this GLTFState. diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index aa482615da..7cac61304f 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -117,7 +117,7 @@ static Ref<ImporterMesh> _mesh_to_importer_mesh(Ref<Mesh> p_mesh) { mat_name = mat->get_name(); } else { // Assign default material when no material is assigned. - mat = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + mat.instantiate(); } importer_mesh->add_surface(p_mesh->surface_get_primitive_type(surface_i), array, p_mesh->surface_get_blend_shape_arrays(surface_i), p_mesh->surface_get_lods(surface_i), mat, @@ -5913,7 +5913,7 @@ void GLTFDocument::_convert_csg_shape_to_gltf(CSGShape3D *p_current, GLTFNodeInd mat_name = mat->get_name(); } else { // Assign default material when no material is assigned. - mat = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + mat.instantiate(); } mesh->add_surface(csg_mesh->surface_get_primitive_type(surface_i), @@ -8560,7 +8560,7 @@ Error GLTFDocument::append_from_file(String p_path, Ref<GLTFState> p_state, uint Error err; Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::READ, &err); - ERR_FAIL_COND_V(err != OK, ERR_FILE_CANT_OPEN); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat(R"(Can't open file at path "%s")", p_path)); ERR_FAIL_COND_V(file.is_null(), ERR_FILE_CANT_OPEN); String base_path = p_base_path; if (base_path.is_empty()) { diff --git a/modules/gltf/tests/test_gltf_extras.h b/modules/gltf/tests/test_gltf_extras.h index 37c8f6925c..73ef02e9f1 100644 --- a/modules/gltf/tests/test_gltf_extras.h +++ b/modules/gltf/tests/test_gltf_extras.h @@ -91,7 +91,7 @@ static Node *_gltf_export_then_import(Node *p_root, String &p_tempfilebase) { options["gltf/naming_version"] = 1; // Process gltf file, note that this generates `.scn` resource from the 2nd argument. - err = import_scene->import(p_tempfilebase + ".gltf", p_tempfilebase, options, nullptr, nullptr, nullptr); + err = import_scene->import(0, p_tempfilebase + ".gltf", p_tempfilebase, options, nullptr, nullptr, nullptr); CHECK_MESSAGE(err == OK, "GLTF import failed."); ResourceImporterScene::remove_scene_importer(import_gltf); diff --git a/modules/godot_physics_3d/godot_shape_3d.cpp b/modules/godot_physics_3d/godot_shape_3d.cpp index a7cccc5cb8..4356ebe2f2 100644 --- a/modules/godot_physics_3d/godot_shape_3d.cpp +++ b/modules/godot_physics_3d/godot_shape_3d.cpp @@ -1996,7 +1996,11 @@ bool GodotHeightMapShape3D::intersect_segment(const Vector3 &p_begin, const Vect Vector3 bounds_from = p_begin / BOUNDS_CHUNK_SIZE; Vector3 bounds_to = p_end / BOUNDS_CHUNK_SIZE; Vector3 bounds_offset = local_origin / BOUNDS_CHUNK_SIZE; - return _intersect_grid_segment(_heightmap_chunk_cull_segment, bounds_from, bounds_to, bounds_grid_width, bounds_grid_depth, bounds_offset, r_point, r_normal); + // Plus 1 here to width and depth of the chunk because _intersect_grid_segment() is used by cell level as well, + // and in _intersect_grid_segment() the loop will exit 1 early because for cell point triangle lookup, it dose x + 1, z + 1 etc for the vertex. + int bounds_width = bounds_grid_width + 1; + int bounds_depth = bounds_grid_depth + 1; + return _intersect_grid_segment(_heightmap_chunk_cull_segment, bounds_from, bounds_to, bounds_width, bounds_depth, bounds_offset, r_point, r_normal); } } diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp index bd2792d92a..432ce5ffa3 100644 --- a/modules/gridmap/editor/grid_map_editor_plugin.cpp +++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp @@ -34,11 +34,14 @@ #include "core/input/input.h" #include "core/os/keyboard.h" +#include "editor/editor_command_palette.h" #include "editor/editor_main_screen.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_string_names.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_bottom_panel.h" +#include "editor/gui/editor_zoom_widget.h" #include "editor/plugins/node_3d_editor_plugin.h" #include "editor/themes/editor_scale.h" #include "scene/3d/camera_3d.h" @@ -84,16 +87,10 @@ void GridMapEditor::_menu_option(int p_option) { } if (edit_axis != new_axis) { - int item1 = options->get_popup()->get_item_index(MENU_OPTION_NEXT_LEVEL); - int item2 = options->get_popup()->get_item_index(MENU_OPTION_PREV_LEVEL); if (edit_axis == Vector3::AXIS_Y) { - options->get_popup()->set_item_text(item1, TTR("Next Plane")); - options->get_popup()->set_item_text(item2, TTR("Previous Plane")); - spin_box_label->set_text(TTR("Plane:")); + floor->set_tooltip_text("Change Grid Plane"); } else if (new_axis == Vector3::AXIS_Y) { - options->get_popup()->set_item_text(item1, TTR("Next Floor")); - options->get_popup()->set_item_text(item2, TTR("Previous Floor")); - spin_box_label->set_text(TTR("Floor:")); + floor->set_tooltip_text("Change Grid Floor"); } } edit_axis = Vector3::Axis(new_axis); @@ -251,14 +248,22 @@ void GridMapEditor::_menu_option(int p_option) { void GridMapEditor::_update_cursor_transform() { cursor_transform = Transform3D(); cursor_transform.origin = cursor_origin; - cursor_transform.basis = node->get_basis_with_orthogonal_index(cursor_rot); cursor_transform.basis *= node->get_cell_scale(); cursor_transform = node->get_global_transform() * cursor_transform; - if (selected_palette >= 0) { - if (node && !node->get_mesh_library().is_null()) { + if (mode_buttons_group->get_pressed_button() == paint_mode_button) { + // Rotation is only applied in paint mode, we don't want the cursor box to rotate otherwise. + cursor_transform.basis = node->get_basis_with_orthogonal_index(cursor_rot); + if (selected_palette >= 0 && node && node->get_mesh_library().is_valid()) { cursor_transform *= node->get_mesh_library()->get_item_mesh_transform(selected_palette); } + } else { + Transform3D xf; + xf.scale(node->get_cell_size()); + xf.origin.x = node->get_center_x() ? -node->get_cell_size().x / 2 : 0; + xf.origin.y = node->get_center_y() ? -node->get_cell_size().y / 2 : 0; + xf.origin.z = node->get_center_z() ? -node->get_cell_size().z / 2 : 0; + cursor_transform *= xf; } if (cursor_instance.is_valid()) { @@ -301,7 +306,7 @@ void GridMapEditor::_update_selection_transform() { xf2.basis.scale(scale); xf2.origin = position; - RenderingServer::get_singleton()->instance_set_transform(selection_level_instance[i], xf2); + RenderingServer::get_singleton()->instance_set_transform(selection_level_instance[i], node->get_global_transform() * xf2); } } } @@ -336,25 +341,22 @@ void GridMapEditor::_set_selection(bool p_active, const Vector3 &p_begin, const if (is_visible_in_tree()) { _update_selection_transform(); } - - options->get_popup()->set_item_disabled(options->get_popup()->get_item_index(MENU_OPTION_SELECTION_CLEAR), !selection.active); - options->get_popup()->set_item_disabled(options->get_popup()->get_item_index(MENU_OPTION_SELECTION_CUT), !selection.active); - options->get_popup()->set_item_disabled(options->get_popup()->get_item_index(MENU_OPTION_SELECTION_DUPLICATE), !selection.active); - options->get_popup()->set_item_disabled(options->get_popup()->get_item_index(MENU_OPTION_SELECTION_FILL), !selection.active); } bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, bool p_click) { if (!spatial_editor) { return false; } - - if (selected_palette < 0 && input_action != INPUT_PICK && input_action != INPUT_SELECT && input_action != INPUT_PASTE) { + if (input_action == INPUT_TRANSFORM) { + return false; + } + if (selected_palette < 0 && input_action != INPUT_NONE && input_action != INPUT_PICK && input_action != INPUT_SELECT && input_action != INPUT_PASTE) { return false; } if (mesh_library.is_null()) { return false; } - if (input_action != INPUT_PICK && input_action != INPUT_SELECT && input_action != INPUT_PASTE && !mesh_library->has_item(selected_palette)) { + if (input_action != INPUT_NONE && input_action != INPUT_PICK && input_action != INPUT_SELECT && input_action != INPUT_PASTE && !mesh_library->has_item(selected_palette)) { return false; } @@ -405,13 +407,17 @@ bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, b cursor_origin = (Vector3(cell[0], cell[1], cell[2]) + Vector3(0.5 * node->get_center_x(), 0.5 * node->get_center_y(), 0.5 * node->get_center_z())) * node->get_cell_size(); cursor_visible = true; - if (input_action == INPUT_SELECT || input_action == INPUT_PASTE) { + if (input_action == INPUT_PASTE) { cursor_visible = false; } _update_cursor_transform(); } + if (input_action == INPUT_NONE) { + return false; + } + if (input_action == INPUT_PASTE) { paste_indicator.current = Vector3i(cell[0], cell[1], cell[2]); _update_paste_indicator(); @@ -604,7 +610,18 @@ void GridMapEditor::_do_paste() { } if (reselect) { - undo_redo->add_do_method(this, "_set_selection", true, paste_indicator.begin + ofs, paste_indicator.end + ofs); + // We need to rotate the paste_indicator to find the selection begin and end: + Vector3 temp_end = rot.xform(paste_indicator.end - paste_indicator.begin) + paste_indicator.begin + ofs; + Vector3 temp_begin = paste_indicator.begin + ofs; + // _set_selection expects that selection_begin is the corner closer to the origin: + for (int i = 0; i < 3; ++i) { + if (temp_begin[i] > temp_end[i]) { + float p = temp_begin[i]; + temp_begin[i] = temp_end[i]; + temp_end[i] = p; + } + } + undo_redo->add_do_method(this, "_set_selection", true, temp_begin, temp_end); undo_redo->add_undo_method(this, "_set_selection", selection.active, selection.begin, selection.end); } @@ -613,13 +630,92 @@ void GridMapEditor::_do_paste() { _clear_clipboard_data(); } +void GridMapEditor::_show_viewports_transform_gizmo(bool p_value) { + Dictionary new_state; + new_state["transform_gizmo"] = p_value; + for (uint32_t i = 0; i < Node3DEditor::VIEWPORTS_COUNT; i++) { + Node3DEditorViewport *viewport = Node3DEditor::get_singleton()->get_editor_viewport(i); + viewport->set_state(new_state); + } +} + EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<InputEvent> &p_event) { if (!node) { return EditorPlugin::AFTER_GUI_INPUT_PASS; } - Ref<InputEventMouseButton> mb = p_event; + Ref<InputEventKey> k = p_event; + if (k.is_valid() && k->is_pressed() && !k->is_echo()) { + // Transform mode (toggle button): + // If we are in Transform mode we pass the events to the 3D editor, + // but if the Transform mode shortcut is pressed again, we go back to Selection mode. + if (mode_buttons_group->get_pressed_button() == transform_mode_button) { + if (transform_mode_button->get_shortcut().is_valid() && transform_mode_button->get_shortcut()->matches_event(p_event)) { + select_mode_button->set_pressed(true); + accept_event(); + return EditorPlugin::AFTER_GUI_INPUT_STOP; + } + return EditorPlugin::AFTER_GUI_INPUT_PASS; + } + // Tool modes and tool actions: + for (BaseButton *b : viewport_shortcut_buttons) { + if (b->is_disabled()) { + continue; + } + + if (b->get_shortcut().is_valid() && b->get_shortcut()->matches_event(p_event)) { + if (b->is_toggle_mode()) { + b->set_pressed(b->get_button_group().is_valid() || !b->is_pressed()); + } else { + // Can't press a button without toggle mode, so just emit the signal directly. + b->emit_signal(SceneStringName(pressed)); + } + accept_event(); + return EditorPlugin::AFTER_GUI_INPUT_STOP; + } + } + // Hard key actions: + if (k->get_keycode() == Key::ESCAPE) { + if (input_action == INPUT_PASTE) { + _clear_clipboard_data(); + input_action = INPUT_NONE; + _update_paste_indicator(); + return EditorPlugin::AFTER_GUI_INPUT_STOP; + } else if (selection.active) { + _set_selection(false); + return EditorPlugin::AFTER_GUI_INPUT_STOP; + } else { + input_action = INPUT_NONE; + update_palette(); + _update_cursor_instance(); + return EditorPlugin::AFTER_GUI_INPUT_STOP; + } + } + // Options menu shortcuts: + Ref<Shortcut> ed_shortcut = ED_GET_SHORTCUT("grid_map/previous_floor"); + if (ed_shortcut.is_valid() && ed_shortcut->matches_event(p_event)) { + accept_event(); + _menu_option(MENU_OPTION_PREV_LEVEL); + return EditorPlugin::AFTER_GUI_INPUT_STOP; + } + ed_shortcut = ED_GET_SHORTCUT("grid_map/next_floor"); + if (ed_shortcut.is_valid() && ed_shortcut->matches_event(p_event)) { + accept_event(); + _menu_option(MENU_OPTION_NEXT_LEVEL); + return EditorPlugin::AFTER_GUI_INPUT_STOP; + } + for (int i = 0; i < options->get_popup()->get_item_count(); ++i) { + const Ref<Shortcut> &shortcut = options->get_popup()->get_item_shortcut(i); + if (shortcut.is_valid() && shortcut->matches_event(p_event)) { + // Consume input to avoid conflicts with other plugins. + accept_event(); + _menu_option(options->get_popup()->get_item_id(i)); + return EditorPlugin::AFTER_GUI_INPUT_STOP; + } + } + } + Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid()) { if (mb->get_button_index() == MouseButton::WHEEL_UP && (mb->is_command_or_control_pressed())) { if (mb->is_pressed()) { @@ -645,14 +741,17 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D input_action = INPUT_NONE; _update_paste_indicator(); return EditorPlugin::AFTER_GUI_INPUT_STOP; - } else if (mb->is_shift_pressed() && can_edit) { + } else if (mode_buttons_group->get_pressed_button() == select_mode_button && can_edit) { input_action = INPUT_SELECT; last_selection = selection; - } else if (mb->is_command_or_control_pressed() && can_edit) { + } else if (mode_buttons_group->get_pressed_button() == pick_mode_button && can_edit) { input_action = INPUT_PICK; - } else { + } else if (mode_buttons_group->get_pressed_button() == paint_mode_button && can_edit) { input_action = INPUT_PAINT; set_items.clear(); + } else if (mode_buttons_group->get_pressed_button() == erase_mode_button && can_edit) { + input_action = INPUT_ERASE; + set_items.clear(); } } else if (mb->get_button_index() == MouseButton::RIGHT) { if (input_action == INPUT_PASTE) { @@ -663,9 +762,6 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D } else if (selection.active) { _set_selection(false); return EditorPlugin::AFTER_GUI_INPUT_STOP; - } else { - input_action = INPUT_ERASE; - set_items.clear(); } } else { return EditorPlugin::AFTER_GUI_INPUT_PASS; @@ -676,7 +772,7 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D } return EditorPlugin::AFTER_GUI_INPUT_PASS; } else { - if ((mb->get_button_index() == MouseButton::RIGHT && input_action == INPUT_ERASE) || (mb->get_button_index() == MouseButton::LEFT && input_action == INPUT_PAINT)) { + if ((mb->get_button_index() == MouseButton::LEFT && input_action == INPUT_ERASE) || (mb->get_button_index() == MouseButton::LEFT && input_action == INPUT_PAINT)) { if (set_items.size()) { EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); undo_redo->create_action(TTR("GridMap Paint")); @@ -731,42 +827,6 @@ EditorPlugin::AfterGUIInput GridMapEditor::forward_spatial_input_event(Camera3D return EditorPlugin::AFTER_GUI_INPUT_PASS; } - Ref<InputEventKey> k = p_event; - - if (k.is_valid()) { - if (k->is_pressed()) { - if (k->get_keycode() == Key::ESCAPE) { - if (input_action == INPUT_PASTE) { - _clear_clipboard_data(); - input_action = INPUT_NONE; - _update_paste_indicator(); - return EditorPlugin::AFTER_GUI_INPUT_STOP; - } else if (selection.active) { - _set_selection(false); - return EditorPlugin::AFTER_GUI_INPUT_STOP; - } else { - selected_palette = -1; - mesh_library_palette->deselect_all(); - update_palette(); - _update_cursor_instance(); - return EditorPlugin::AFTER_GUI_INPUT_STOP; - } - } - - // Consume input to avoid conflicts with other plugins. - if (k.is_valid() && k->is_pressed() && !k->is_echo()) { - for (int i = 0; i < options->get_popup()->get_item_count(); ++i) { - const Ref<Shortcut> &shortcut = options->get_popup()->get_item_shortcut(i); - if (shortcut.is_valid() && shortcut->matches_event(p_event)) { - accept_event(); - _menu_option(options->get_popup()->get_item_id(i)); - return EditorPlugin::AFTER_GUI_INPUT_STOP; - } - } - } - } - } - Ref<InputEventPanGesture> pan_gesture = p_event; if (pan_gesture.is_valid()) { if (pan_gesture->is_alt_pressed() && pan_gesture->is_command_or_control_pressed()) { @@ -833,11 +893,13 @@ void GridMapEditor::_mesh_library_palette_input(const Ref<InputEvent> &p_ie) { // Zoom in/out using Ctrl + mouse wheel if (mb.is_valid() && mb->is_pressed() && mb->is_command_or_control_pressed()) { if (mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) { - size_slider->set_value(size_slider->get_value() + 0.2); + zoom_widget->set_zoom(zoom_widget->get_zoom() + 0.2); + zoom_widget->emit_signal(SNAME("zoom_changed"), zoom_widget->get_zoom()); } if (mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN) { - size_slider->set_value(size_slider->get_value() - 0.2); + zoom_widget->set_zoom(zoom_widget->get_zoom() - 0.2); + zoom_widget->emit_signal(SNAME("zoom_changed"), zoom_widget->get_zoom()); } } } @@ -855,9 +917,9 @@ void GridMapEditor::update_palette() { if (display_mode == DISPLAY_THUMBNAIL) { mesh_library_palette->set_max_columns(0); mesh_library_palette->set_icon_mode(ItemList::ICON_MODE_TOP); - mesh_library_palette->set_fixed_column_width(min_size * MAX(size_slider->get_value(), 1.5)); + mesh_library_palette->set_fixed_column_width(min_size * MAX(zoom_widget->get_zoom(), 1.5)); } else if (display_mode == DISPLAY_LIST) { - mesh_library_palette->set_max_columns(1); + mesh_library_palette->set_max_columns(0); mesh_library_palette->set_icon_mode(ItemList::ICON_MODE_LEFT); mesh_library_palette->set_fixed_column_width(0); } @@ -938,6 +1000,11 @@ void GridMapEditor::_update_mesh_library() { } update_palette(); + // Make sure we select the first tile as default possible. + if (mesh_library_palette->get_current() == -1 && mesh_library_palette->get_item_count() > 0) { + mesh_library_palette->set_current(0); + selected_palette = mesh_library_palette->get_item_metadata(0); + } // Update the cursor and grid in case the library is changed or removed. _update_cursor_instance(); update_grid(); @@ -1058,10 +1125,22 @@ void GridMapEditor::_draw_grids(const Vector3 &cell_size) { } void GridMapEditor::_update_theme() { - options->set_button_icon(get_theme_icon(SNAME("GridMap"), EditorStringName(EditorIcons))); + transform_mode_button->set_button_icon(get_theme_icon(SNAME("ToolMove"), EditorStringName(EditorIcons))); + select_mode_button->set_button_icon(get_theme_icon(SNAME("ToolSelect"), EditorStringName(EditorIcons))); + erase_mode_button->set_button_icon(get_theme_icon(SNAME("Eraser"), EditorStringName(EditorIcons))); + paint_mode_button->set_button_icon(get_theme_icon(SNAME("Paint"), EditorStringName(EditorIcons))); + pick_mode_button->set_button_icon(get_theme_icon(SNAME("ColorPick"), EditorStringName(EditorIcons))); + fill_action_button->set_button_icon(get_theme_icon(SNAME("Bucket"), EditorStringName(EditorIcons))); + move_action_button->set_button_icon(get_theme_icon(SNAME("ActionCut"), EditorStringName(EditorIcons))); + duplicate_action_button->set_button_icon(get_theme_icon(SNAME("ActionCopy"), EditorStringName(EditorIcons))); + delete_action_button->set_button_icon(get_theme_icon(SNAME("Clear"), EditorStringName(EditorIcons))); + rotate_x_button->set_button_icon(get_theme_icon(SNAME("RotateLeft"), EditorStringName(EditorIcons))); + rotate_y_button->set_button_icon(get_theme_icon(SNAME("ToolRotate"), EditorStringName(EditorIcons))); + rotate_z_button->set_button_icon(get_theme_icon(SNAME("RotateRight"), EditorStringName(EditorIcons))); search_box->set_right_icon(get_theme_icon(SNAME("Search"), EditorStringName(EditorIcons))); mode_thumbnail->set_button_icon(get_theme_icon(SNAME("FileThumbnail"), EditorStringName(EditorIcons))); mode_list->set_button_icon(get_theme_icon(SNAME("FileList"), EditorStringName(EditorIcons))); + options->set_button_icon(get_theme_icon(SNAME("Tools"), EditorStringName(EditorIcons))); } void GridMapEditor::_notification(int p_what) { @@ -1076,6 +1155,9 @@ void GridMapEditor::_notification(int p_what) { RenderingServer::get_singleton()->instance_set_layer_mask(selection_level_instance[i], 1 << Node3DEditorViewport::MISC_TOOL_LAYER); } + cursor_instance = RenderingServer::get_singleton()->instance_create2(cursor_mesh, get_tree()->get_root()->get_world_3d()->get_scenario()); + RenderingServer::get_singleton()->instance_set_layer_mask(cursor_instance, 1 << Node3DEditorViewport::MISC_TOOL_LAYER); + RenderingServer::get_singleton()->instance_set_visible(cursor_instance, false); selection_instance = RenderingServer::get_singleton()->instance_create2(selection_mesh, get_tree()->get_root()->get_world_3d()->get_scenario()); RenderingServer::get_singleton()->instance_set_layer_mask(selection_instance, 1 << Node3DEditorViewport::MISC_TOOL_LAYER); paste_instance = RenderingServer::get_singleton()->instance_create2(paste_mesh, get_tree()->get_root()->get_world_3d()->get_scenario()); @@ -1097,8 +1179,10 @@ void GridMapEditor::_notification(int p_what) { RenderingServer::get_singleton()->free(selection_level_instance[i]); } + RenderingServer::get_singleton()->free(cursor_instance); RenderingServer::get_singleton()->free(selection_instance); RenderingServer::get_singleton()->free(paste_instance); + cursor_instance = RID(); selection_instance = RID(); paste_instance = RID(); } break; @@ -1144,15 +1228,32 @@ void GridMapEditor::_update_cursor_instance() { } cursor_instance = RID(); - if (selected_palette >= 0) { - if (node && !node->get_mesh_library().is_null()) { + if (mode_buttons_group->get_pressed_button() == paint_mode_button) { + if (selected_palette >= 0 && node && node->get_mesh_library().is_valid()) { Ref<Mesh> mesh = node->get_mesh_library()->get_item_mesh(selected_palette); if (!mesh.is_null() && mesh->get_rid().is_valid()) { cursor_instance = RenderingServer::get_singleton()->instance_create2(mesh->get_rid(), get_tree()->get_root()->get_world_3d()->get_scenario()); - RenderingServer::get_singleton()->instance_set_transform(cursor_instance, cursor_transform); } } + } else if (mode_buttons_group->get_pressed_button() == select_mode_button) { + cursor_inner_mat->set_albedo(Color(default_color, 0.2)); + cursor_outer_mat->set_albedo(Color(default_color, 0.8)); + cursor_instance = RenderingServer::get_singleton()->instance_create2(cursor_mesh, get_tree()->get_root()->get_world_3d()->get_scenario()); + } else if (mode_buttons_group->get_pressed_button() == erase_mode_button) { + cursor_inner_mat->set_albedo(Color(erase_color, 0.2)); + cursor_outer_mat->set_albedo(Color(erase_color, 0.8)); + cursor_instance = RenderingServer::get_singleton()->instance_create2(cursor_mesh, get_tree()->get_root()->get_world_3d()->get_scenario()); + } else if (mode_buttons_group->get_pressed_button() == pick_mode_button) { + cursor_inner_mat->set_albedo(Color(pick_color, 0.2)); + cursor_outer_mat->set_albedo(Color(pick_color, 0.8)); + cursor_instance = RenderingServer::get_singleton()->instance_create2(cursor_mesh, get_tree()->get_root()->get_world_3d()->get_scenario()); } + _update_cursor_transform(); +} + +void GridMapEditor::_on_tool_mode_changed() { + _show_viewports_transform_gizmo(mode_buttons_group->get_pressed_button() == transform_mode_button); + _update_cursor_instance(); } void GridMapEditor::_item_selected_cbk(int idx) { @@ -1182,80 +1283,26 @@ void GridMapEditor::_bind_methods() { } GridMapEditor::GridMapEditor() { - ED_SHORTCUT("grid_map/previous_floor", TTR("Previous Floor"), Key::Q, true); - ED_SHORTCUT("grid_map/next_floor", TTR("Next Floor"), Key::E, true); - ED_SHORTCUT("grid_map/edit_x_axis", TTR("Edit X Axis"), Key::Z, true); - ED_SHORTCUT("grid_map/edit_y_axis", TTR("Edit Y Axis"), Key::X, true); - ED_SHORTCUT("grid_map/edit_z_axis", TTR("Edit Z Axis"), Key::C, true); - ED_SHORTCUT("grid_map/cursor_rotate_x", TTR("Cursor Rotate X"), Key::A, true); - ED_SHORTCUT("grid_map/cursor_rotate_y", TTR("Cursor Rotate Y"), Key::S, true); - ED_SHORTCUT("grid_map/cursor_rotate_z", TTR("Cursor Rotate Z"), Key::D, true); - ED_SHORTCUT("grid_map/cursor_back_rotate_x", TTR("Cursor Back Rotate X"), KeyModifierMask::SHIFT + Key::A, true); - ED_SHORTCUT("grid_map/cursor_back_rotate_y", TTR("Cursor Back Rotate Y"), KeyModifierMask::SHIFT + Key::S, true); - ED_SHORTCUT("grid_map/cursor_back_rotate_z", TTR("Cursor Back Rotate Z"), KeyModifierMask::SHIFT + Key::D, true); - ED_SHORTCUT("grid_map/cursor_clear_rotation", TTR("Cursor Clear Rotation"), Key::W, true); - ED_SHORTCUT("grid_map/paste_selects", TTR("Paste Selects")); - ED_SHORTCUT("grid_map/duplicate_selection", TTR("Duplicate Selection"), KeyModifierMask::CTRL + Key::C); - ED_SHORTCUT("grid_map/cut_selection", TTR("Cut Selection"), KeyModifierMask::CTRL + Key::X); - ED_SHORTCUT("grid_map/clear_selection", TTR("Clear Selection"), Key::KEY_DELETE); - ED_SHORTCUT("grid_map/fill_selection", TTR("Fill Selection"), KeyModifierMask::CTRL + Key::F); - - int mw = EDITOR_GET("editors/grid_map/palette_min_width"); - Control *ec = memnew(Control); - ec->set_custom_minimum_size(Size2(mw, 0) * EDSCALE); - add_child(ec); - - spatial_editor_hb = memnew(HBoxContainer); - spatial_editor_hb->set_h_size_flags(SIZE_EXPAND_FILL); - spatial_editor_hb->set_alignment(BoxContainer::ALIGNMENT_END); - Node3DEditor::get_singleton()->add_control_to_menu_panel(spatial_editor_hb); - - spin_box_label = memnew(Label); - spin_box_label->set_text(TTR("Floor:")); - spatial_editor_hb->add_child(spin_box_label); - - floor = memnew(SpinBox); - floor->set_min(-32767); - floor->set_max(32767); - floor->set_step(1); - floor->get_line_edit()->add_theme_constant_override("minimum_character_width", 16); - - spatial_editor_hb->add_child(floor); - floor->connect(SceneStringName(value_changed), callable_mp(this, &GridMapEditor::_floor_changed)); - floor->connect(SceneStringName(mouse_exited), callable_mp(this, &GridMapEditor::_floor_mouse_exited)); - floor->get_line_edit()->connect(SceneStringName(mouse_exited), callable_mp(this, &GridMapEditor::_floor_mouse_exited)); - - spatial_editor_hb->add_child(memnew(VSeparator)); + ED_SHORTCUT("grid_map/previous_floor", TTR("Previous Floor"), Key::KEY_1, true); + ED_SHORTCUT("grid_map/next_floor", TTR("Next Floor"), Key::KEY_3, true); + ED_SHORTCUT("grid_map/edit_x_axis", TTR("Edit X Axis"), KeyModifierMask::SHIFT + Key::Z, true); + ED_SHORTCUT("grid_map/edit_y_axis", TTR("Edit Y Axis"), KeyModifierMask::SHIFT + Key::X, true); + ED_SHORTCUT("grid_map/edit_z_axis", TTR("Edit Z Axis"), KeyModifierMask::SHIFT + Key::C, true); + ED_SHORTCUT("grid_map/keep_selected", TTR("Keep Selection")); + ED_SHORTCUT("grid_map/clear_rotation", TTR("Clear Rotation")); options = memnew(MenuButton); - spatial_editor_hb->add_child(options); - spatial_editor_hb->hide(); - - options->set_text(TTR("Grid Map")); - options->get_popup()->add_shortcut(ED_GET_SHORTCUT("grid_map/previous_floor"), MENU_OPTION_PREV_LEVEL); - options->get_popup()->add_shortcut(ED_GET_SHORTCUT("grid_map/next_floor"), MENU_OPTION_NEXT_LEVEL); + options->set_theme_type_variation("FlatButton"); options->get_popup()->add_separator(); options->get_popup()->add_radio_check_shortcut(ED_GET_SHORTCUT("grid_map/edit_x_axis"), MENU_OPTION_X_AXIS); options->get_popup()->add_radio_check_shortcut(ED_GET_SHORTCUT("grid_map/edit_y_axis"), MENU_OPTION_Y_AXIS); options->get_popup()->add_radio_check_shortcut(ED_GET_SHORTCUT("grid_map/edit_z_axis"), MENU_OPTION_Z_AXIS); options->get_popup()->set_item_checked(options->get_popup()->get_item_index(MENU_OPTION_Y_AXIS), true); options->get_popup()->add_separator(); - options->get_popup()->add_shortcut(ED_GET_SHORTCUT("grid_map/cursor_rotate_x"), MENU_OPTION_CURSOR_ROTATE_X); - options->get_popup()->add_shortcut(ED_GET_SHORTCUT("grid_map/cursor_rotate_y"), MENU_OPTION_CURSOR_ROTATE_Y); - options->get_popup()->add_shortcut(ED_GET_SHORTCUT("grid_map/cursor_rotate_z"), MENU_OPTION_CURSOR_ROTATE_Z); - options->get_popup()->add_shortcut(ED_GET_SHORTCUT("grid_map/cursor_back_rotate_x"), MENU_OPTION_CURSOR_BACK_ROTATE_X); - options->get_popup()->add_shortcut(ED_GET_SHORTCUT("grid_map/cursor_back_rotate_y"), MENU_OPTION_CURSOR_BACK_ROTATE_Y); - options->get_popup()->add_shortcut(ED_GET_SHORTCUT("grid_map/cursor_back_rotate_z"), MENU_OPTION_CURSOR_BACK_ROTATE_Z); - options->get_popup()->add_shortcut(ED_GET_SHORTCUT("grid_map/cursor_clear_rotation"), MENU_OPTION_CURSOR_CLEAR_ROTATION); - options->get_popup()->add_separator(); // TRANSLATORS: This is a toggle to select after pasting the new content. - options->get_popup()->add_check_shortcut(ED_GET_SHORTCUT("grid_map/paste_selects"), MENU_OPTION_PASTE_SELECTS); - options->get_popup()->add_separator(); - options->get_popup()->add_shortcut(ED_GET_SHORTCUT("grid_map/duplicate_selection"), MENU_OPTION_SELECTION_DUPLICATE); - options->get_popup()->add_shortcut(ED_GET_SHORTCUT("grid_map/cut_selection"), MENU_OPTION_SELECTION_CUT); - options->get_popup()->add_shortcut(ED_GET_SHORTCUT("grid_map/clear_selection"), MENU_OPTION_SELECTION_CLEAR); - options->get_popup()->add_shortcut(ED_GET_SHORTCUT("grid_map/fill_selection"), MENU_OPTION_SELECTION_FILL); - + options->get_popup()->add_shortcut(ED_GET_SHORTCUT("grid_map/clear_rotation"), MENU_OPTION_CURSOR_CLEAR_ROTATION); + options->get_popup()->add_check_shortcut(ED_GET_SHORTCUT("grid_map/keep_selected"), MENU_OPTION_PASTE_SELECTS); + options->get_popup()->set_item_checked(options->get_popup()->get_item_index(MENU_OPTION_PASTE_SELECTS), true); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Settings..."), MENU_OPTION_GRIDMAP_SETTINGS); @@ -1275,40 +1322,187 @@ GridMapEditor::GridMapEditor() { options->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &GridMapEditor::_menu_option)); - HBoxContainer *hb = memnew(HBoxContainer); - add_child(hb); - hb->set_h_size_flags(SIZE_EXPAND_FILL); + toolbar = memnew(HBoxContainer); + add_child(toolbar); + toolbar->set_h_size_flags(SIZE_EXPAND_FILL); + + HBoxContainer *mode_buttons = memnew(HBoxContainer); + toolbar->add_child(mode_buttons); + mode_buttons_group.instantiate(); + + transform_mode_button = memnew(Button); + transform_mode_button->set_theme_type_variation("FlatButton"); + transform_mode_button->set_toggle_mode(true); + transform_mode_button->set_button_group(mode_buttons_group); + transform_mode_button->set_shortcut(ED_SHORTCUT("grid_map/transform_tool", TTR("Transform"), Key::T, true)); + transform_mode_button->connect(SceneStringName(toggled), + callable_mp(this, &GridMapEditor::_on_tool_mode_changed).unbind(1)); + mode_buttons->add_child(transform_mode_button); + viewport_shortcut_buttons.push_back(transform_mode_button); + VSeparator *vsep = memnew(VSeparator); + mode_buttons->add_child(vsep); + + select_mode_button = memnew(Button); + select_mode_button->set_theme_type_variation("FlatButton"); + select_mode_button->set_toggle_mode(true); + select_mode_button->set_button_group(mode_buttons_group); + select_mode_button->set_shortcut(ED_SHORTCUT("grid_map/selection_tool", TTR("Selection"), Key::Q, true)); + select_mode_button->connect(SceneStringName(toggled), + callable_mp(this, &GridMapEditor::_on_tool_mode_changed).unbind(1)); + mode_buttons->add_child(select_mode_button); + viewport_shortcut_buttons.push_back(select_mode_button); + select_mode_button->set_pressed(true); + + erase_mode_button = memnew(Button); + erase_mode_button->set_theme_type_variation("FlatButton"); + erase_mode_button->set_toggle_mode(true); + erase_mode_button->set_button_group(mode_buttons_group); + erase_mode_button->set_shortcut(ED_SHORTCUT("grid_map/erase_tool", TTR("Erase"), Key::W, true)); + mode_buttons->add_child(erase_mode_button); + erase_mode_button->connect(SceneStringName(toggled), + callable_mp(this, &GridMapEditor::_on_tool_mode_changed).unbind(1)); + viewport_shortcut_buttons.push_back(erase_mode_button); + + paint_mode_button = memnew(Button); + paint_mode_button->set_theme_type_variation("FlatButton"); + paint_mode_button->set_toggle_mode(true); + paint_mode_button->set_button_group(mode_buttons_group); + paint_mode_button->set_shortcut(ED_SHORTCUT("grid_map/paint_tool", TTR("Paint"), Key::E, true)); + paint_mode_button->connect(SceneStringName(toggled), + callable_mp(this, &GridMapEditor::_on_tool_mode_changed).unbind(1)); + mode_buttons->add_child(paint_mode_button); + viewport_shortcut_buttons.push_back(paint_mode_button); + + pick_mode_button = memnew(Button); + pick_mode_button->set_theme_type_variation("FlatButton"); + pick_mode_button->set_toggle_mode(true); + pick_mode_button->set_button_group(mode_buttons_group); + pick_mode_button->set_shortcut(ED_SHORTCUT("grid_map/pick_tool", TTR("Pick"), Key::R, true)); + pick_mode_button->connect(SceneStringName(toggled), + callable_mp(this, &GridMapEditor::_on_tool_mode_changed).unbind(1)); + mode_buttons->add_child(pick_mode_button); + viewport_shortcut_buttons.push_back(pick_mode_button); + + vsep = memnew(VSeparator); + toolbar->add_child(vsep); + + HBoxContainer *action_buttons = memnew(HBoxContainer); + toolbar->add_child(action_buttons); + + fill_action_button = memnew(Button); + fill_action_button->set_theme_type_variation("FlatButton"); + fill_action_button->set_shortcut(ED_SHORTCUT("grid_map/fill_tool", TTR("Fill"), Key::Z, true)); + fill_action_button->connect(SceneStringName(pressed), + callable_mp(this, &GridMapEditor::_menu_option).bind(MENU_OPTION_SELECTION_FILL)); + action_buttons->add_child(fill_action_button); + viewport_shortcut_buttons.push_back(fill_action_button); + + move_action_button = memnew(Button); + move_action_button->set_theme_type_variation("FlatButton"); + move_action_button->set_shortcut(ED_SHORTCUT("grid_map/move_tool", TTR("Move"), Key::X, true)); + move_action_button->connect(SceneStringName(pressed), + callable_mp(this, &GridMapEditor::_menu_option).bind(MENU_OPTION_SELECTION_CUT)); + action_buttons->add_child(move_action_button); + viewport_shortcut_buttons.push_back(move_action_button); + + duplicate_action_button = memnew(Button); + duplicate_action_button->set_theme_type_variation("FlatButton"); + duplicate_action_button->set_shortcut(ED_SHORTCUT("grid_map/duplicate_tool", TTR("Duplicate"), Key::C, true)); + duplicate_action_button->connect(SceneStringName(pressed), + callable_mp(this, &GridMapEditor::_menu_option).bind(MENU_OPTION_SELECTION_DUPLICATE)); + action_buttons->add_child(duplicate_action_button); + viewport_shortcut_buttons.push_back(duplicate_action_button); + + delete_action_button = memnew(Button); + delete_action_button->set_theme_type_variation("FlatButton"); + delete_action_button->set_shortcut(ED_SHORTCUT("grid_map/delete_tool", TTR("Delete"), Key::V, true)); + delete_action_button->connect(SceneStringName(pressed), + callable_mp(this, &GridMapEditor::_menu_option).bind(MENU_OPTION_SELECTION_CLEAR)); + action_buttons->add_child(delete_action_button); + viewport_shortcut_buttons.push_back(delete_action_button); + + vsep = memnew(VSeparator); + toolbar->add_child(vsep); + + HBoxContainer *rotation_buttons = memnew(HBoxContainer); + toolbar->add_child(rotation_buttons); + + rotate_x_button = memnew(Button); + rotate_x_button->set_theme_type_variation("FlatButton"); + rotate_x_button->set_shortcut(ED_SHORTCUT("grid_map/cursor_rotate_x", TTR("Cursor Rotate X"), Key::A, true)); + rotate_x_button->connect(SceneStringName(pressed), + callable_mp(this, &GridMapEditor::_menu_option).bind(MENU_OPTION_CURSOR_ROTATE_X)); + rotation_buttons->add_child(rotate_x_button); + viewport_shortcut_buttons.push_back(rotate_x_button); + + rotate_y_button = memnew(Button); + rotate_y_button->set_theme_type_variation("FlatButton"); + rotate_y_button->set_shortcut(ED_SHORTCUT("grid_map/cursor_rotate_y", TTR("Cursor Rotate Y"), Key::S, true)); + rotate_y_button->connect(SceneStringName(pressed), + callable_mp(this, &GridMapEditor::_menu_option).bind(MENU_OPTION_CURSOR_ROTATE_Y)); + rotation_buttons->add_child(rotate_y_button); + viewport_shortcut_buttons.push_back(rotate_y_button); + + rotate_z_button = memnew(Button); + rotate_z_button->set_theme_type_variation("FlatButton"); + rotate_z_button->set_shortcut(ED_SHORTCUT("grid_map/cursor_rotate_z", TTR("Cursor Rotate Z"), Key::D, true)); + rotate_z_button->connect(SceneStringName(pressed), + callable_mp(this, &GridMapEditor::_menu_option).bind(MENU_OPTION_CURSOR_ROTATE_Z)); + rotation_buttons->add_child(rotate_z_button); + viewport_shortcut_buttons.push_back(rotate_z_button); + + // Wide empty separation control. (like BoxContainer::add_spacer()) + Control *c = memnew(Control); + c->set_mouse_filter(MOUSE_FILTER_PASS); + c->set_h_size_flags(SIZE_EXPAND_FILL); + toolbar->add_child(c); + + floor = memnew(SpinBox); + floor->set_min(-32767); + floor->set_max(32767); + floor->set_step(1); + floor->set_tooltip_text( + TTR(vformat("Change Grid Floor:\nPrevious Plane (%s)\nNext Plane (%s)", + ED_GET_SHORTCUT("grid_map/previous_floor")->get_as_text(), + ED_GET_SHORTCUT("grid_map/next_floor")->get_as_text()))); + toolbar->add_child(floor); + floor->get_line_edit()->add_theme_constant_override("minimum_character_width", 2); + floor->get_line_edit()->set_context_menu_enabled(false); + floor->connect(SceneStringName(value_changed), callable_mp(this, &GridMapEditor::_floor_changed)); + floor->connect(SceneStringName(mouse_exited), callable_mp(this, &GridMapEditor::_floor_mouse_exited)); + floor->get_line_edit()->connect(SceneStringName(mouse_exited), callable_mp(this, &GridMapEditor::_floor_mouse_exited)); search_box = memnew(LineEdit); - search_box->set_h_size_flags(SIZE_EXPAND_FILL); + search_box->add_theme_constant_override("minimum_character_width", 10); search_box->set_placeholder(TTR("Filter Meshes")); search_box->set_clear_button_enabled(true); - hb->add_child(search_box); + toolbar->add_child(search_box); search_box->connect(SceneStringName(text_changed), callable_mp(this, &GridMapEditor::_text_changed)); search_box->connect(SceneStringName(gui_input), callable_mp(this, &GridMapEditor::_sbox_input)); + zoom_widget = memnew(EditorZoomWidget); + toolbar->add_child(zoom_widget); + zoom_widget->setup_zoom_limits(0.2, 4); + zoom_widget->set_zoom(1.0); + zoom_widget->set_anchors_and_offsets_preset(Control::PRESET_TOP_LEFT, Control::PRESET_MODE_MINSIZE, 2 * EDSCALE); + zoom_widget->connect("zoom_changed", callable_mp(this, &GridMapEditor::_icon_size_changed)); + zoom_widget->set_shortcut_context(this); + mode_thumbnail = memnew(Button); mode_thumbnail->set_theme_type_variation("FlatButton"); mode_thumbnail->set_toggle_mode(true); mode_thumbnail->set_pressed(true); - hb->add_child(mode_thumbnail); + toolbar->add_child(mode_thumbnail); mode_thumbnail->connect(SceneStringName(pressed), callable_mp(this, &GridMapEditor::_set_display_mode).bind(DISPLAY_THUMBNAIL)); mode_list = memnew(Button); mode_list->set_theme_type_variation("FlatButton"); mode_list->set_toggle_mode(true); mode_list->set_pressed(false); - hb->add_child(mode_list); + toolbar->add_child(mode_list); mode_list->connect(SceneStringName(pressed), callable_mp(this, &GridMapEditor::_set_display_mode).bind(DISPLAY_LIST)); - size_slider = memnew(HSlider); - size_slider->set_h_size_flags(SIZE_EXPAND_FILL); - size_slider->set_min(0.2f); - size_slider->set_max(4.0f); - size_slider->set_step(0.1f); - size_slider->set_value(1.0f); - size_slider->connect(SceneStringName(value_changed), callable_mp(this, &GridMapEditor::_icon_size_changed)); - add_child(size_slider); + toolbar->add_child(options); mesh_library_palette = memnew(ItemList); mesh_library_palette->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); @@ -1330,6 +1524,7 @@ GridMapEditor::GridMapEditor() { edit_floor[1] = -1; edit_floor[2] = -1; + cursor_mesh = RenderingServer::get_singleton()->mesh_create(); selection_mesh = RenderingServer::get_singleton()->mesh_create(); paste_mesh = RenderingServer::get_singleton()->mesh_create(); @@ -1405,20 +1600,32 @@ GridMapEditor::GridMapEditor() { Array d; d.resize(RS::ARRAY_MAX); + default_color = Color(0.0, 0.565, 1.0); // blue 0.7, 0.7, 1.0 + erase_color = Color(1.0, 0.2, 0.2); // red + pick_color = Color(1, 0.7, 0); // orange/yellow + + cursor_inner_mat.instantiate(); + cursor_inner_mat->set_albedo(Color(default_color, 0.2)); + cursor_inner_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + cursor_inner_mat->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); + cursor_inner_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + + cursor_outer_mat.instantiate(); + cursor_outer_mat->set_albedo(Color(default_color, 0.8)); + cursor_outer_mat->set_on_top_of_alpha(); + cursor_outer_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + cursor_outer_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + cursor_outer_mat->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); + inner_mat.instantiate(); - inner_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.2)); + inner_mat->set_albedo(Color(default_color, 0.2)); inner_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); inner_mat->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); inner_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); - d[RS::ARRAY_VERTEX] = triangles; - RenderingServer::get_singleton()->mesh_add_surface_from_arrays(selection_mesh, RS::PRIMITIVE_TRIANGLES, d); - RenderingServer::get_singleton()->mesh_surface_set_material(selection_mesh, 0, inner_mat->get_rid()); - outer_mat.instantiate(); - outer_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.8)); + outer_mat->set_albedo(Color(default_color, 0.8)); outer_mat->set_on_top_of_alpha(); - outer_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); outer_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); outer_mat->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); @@ -1429,6 +1636,18 @@ GridMapEditor::GridMapEditor() { selection_floor_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); selection_floor_mat->set_flag(StandardMaterial3D::FLAG_DISABLE_FOG, true); + d[RS::ARRAY_VERTEX] = triangles; + RenderingServer::get_singleton()->mesh_add_surface_from_arrays(cursor_mesh, RS::PRIMITIVE_TRIANGLES, d); + RenderingServer::get_singleton()->mesh_surface_set_material(cursor_mesh, 0, cursor_inner_mat->get_rid()); + + d[RS::ARRAY_VERTEX] = lines; + RenderingServer::get_singleton()->mesh_add_surface_from_arrays(cursor_mesh, RS::PRIMITIVE_LINES, d); + RenderingServer::get_singleton()->mesh_surface_set_material(cursor_mesh, 1, cursor_outer_mat->get_rid()); + + d[RS::ARRAY_VERTEX] = triangles; + RenderingServer::get_singleton()->mesh_add_surface_from_arrays(selection_mesh, RS::PRIMITIVE_TRIANGLES, d); + RenderingServer::get_singleton()->mesh_surface_set_material(selection_mesh, 0, inner_mat->get_rid()); + d[RS::ARRAY_VERTEX] = lines; RenderingServer::get_singleton()->mesh_add_surface_from_arrays(selection_mesh, RS::PRIMITIVE_LINES, d); RenderingServer::get_singleton()->mesh_surface_set_material(selection_mesh, 1, outer_mat->get_rid()); @@ -1471,9 +1690,6 @@ GridMapEditor::~GridMapEditor() { if (grid_instance[i].is_valid()) { RenderingServer::get_singleton()->free(grid_instance[i]); } - if (cursor_instance.is_valid()) { - RenderingServer::get_singleton()->free(cursor_instance); - } if (selection_level_instance[i].is_valid()) { RenderingServer::get_singleton()->free(selection_level_instance[i]); } @@ -1482,6 +1698,11 @@ GridMapEditor::~GridMapEditor() { } } + RenderingServer::get_singleton()->free(cursor_mesh); + if (cursor_instance.is_valid()) { + RenderingServer::get_singleton()->free(cursor_instance); + } + RenderingServer::get_singleton()->free(selection_mesh); if (selection_instance.is_valid()) { RenderingServer::get_singleton()->free(selection_instance); @@ -1493,24 +1714,6 @@ GridMapEditor::~GridMapEditor() { } } -void GridMapEditorPlugin::_notification(int p_what) { - switch (p_what) { - case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - if (!EditorSettings::get_singleton()->check_changed_settings_in_group("editors/grid_map")) { - break; - } - switch ((int)EDITOR_GET("editors/grid_map/editor_side")) { - case 0: { // Left. - Node3DEditor::get_singleton()->move_control_to_left_panel(grid_map_editor); - } break; - case 1: { // Right. - Node3DEditor::get_singleton()->move_control_to_right_panel(grid_map_editor); - } break; - } - } break; - } -} - void GridMapEditorPlugin::edit(Object *p_object) { grid_map_editor->edit(Object::cast_to<GridMap>(p_object)); } @@ -1521,27 +1724,29 @@ bool GridMapEditorPlugin::handles(Object *p_object) const { void GridMapEditorPlugin::make_visible(bool p_visible) { if (p_visible) { - grid_map_editor->show(); - grid_map_editor->spatial_editor_hb->show(); + grid_map_editor->_on_tool_mode_changed(); + panel_button->show(); + EditorNode::get_bottom_panel()->make_item_visible(grid_map_editor); grid_map_editor->set_process(true); } else { - grid_map_editor->spatial_editor_hb->hide(); - grid_map_editor->hide(); + grid_map_editor->_show_viewports_transform_gizmo(true); + panel_button->hide(); + if (grid_map_editor->is_visible_in_tree()) { + EditorNode::get_bottom_panel()->hide_bottom_panel(); + } grid_map_editor->set_process(false); } } GridMapEditorPlugin::GridMapEditorPlugin() { grid_map_editor = memnew(GridMapEditor); - switch ((int)EDITOR_GET("editors/grid_map/editor_side")) { - case 0: { // Left. - Node3DEditor::get_singleton()->add_control_to_left_panel(grid_map_editor); - } break; - case 1: { // Right. - Node3DEditor::get_singleton()->add_control_to_right_panel(grid_map_editor); - } break; - } + grid_map_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL); + grid_map_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); + grid_map_editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE); grid_map_editor->hide(); + + panel_button = EditorNode::get_bottom_panel()->add_item(TTR("GridMap"), grid_map_editor, ED_SHORTCUT_AND_COMMAND("bottom_panels/toggle_grid_map_bottom_panel", TTR("Toggle GridMap Bottom Panel"))); + panel_button->hide(); } GridMapEditorPlugin::~GridMapEditorPlugin() { diff --git a/modules/gridmap/editor/grid_map_editor_plugin.h b/modules/gridmap/editor/grid_map_editor_plugin.h index 4294c93c93..2d43a5c830 100644 --- a/modules/gridmap/editor/grid_map_editor_plugin.h +++ b/modules/gridmap/editor/grid_map_editor_plugin.h @@ -44,6 +44,9 @@ class ConfirmationDialog; class MenuButton; class Node3DEditorPlugin; +class ButtonGroup; +class EditorZoomWidget; +class BaseButton; class GridMapEditor : public VBoxContainer { GDCLASS(GridMapEditor, VBoxContainer); @@ -54,6 +57,7 @@ class GridMapEditor : public VBoxContainer { enum InputAction { INPUT_NONE, + INPUT_TRANSFORM, INPUT_PAINT, INPUT_ERASE, INPUT_PICK, @@ -71,11 +75,31 @@ class GridMapEditor : public VBoxContainer { MenuButton *options = nullptr; SpinBox *floor = nullptr; double accumulated_floor_delta = 0.0; + + HBoxContainer *toolbar = nullptr; + List<BaseButton *> viewport_shortcut_buttons; + Ref<ButtonGroup> mode_buttons_group; + // mode + Button *transform_mode_button = nullptr; + Button *select_mode_button = nullptr; + Button *erase_mode_button = nullptr; + Button *paint_mode_button = nullptr; + Button *pick_mode_button = nullptr; + // action + Button *fill_action_button = nullptr; + Button *move_action_button = nullptr; + Button *duplicate_action_button = nullptr; + Button *delete_action_button = nullptr; + // rotation + Button *rotate_x_button = nullptr; + Button *rotate_y_button = nullptr; + Button *rotate_z_button = nullptr; + + EditorZoomWidget *zoom_widget = nullptr; Button *mode_thumbnail = nullptr; Button *mode_list = nullptr; LineEdit *search_box = nullptr; HSlider *size_slider = nullptr; - HBoxContainer *spatial_editor_hb = nullptr; ConfirmationDialog *settings_dialog = nullptr; VBoxContainer *settings_vbc = nullptr; SpinBox *settings_pick_distance = nullptr; @@ -102,6 +126,7 @@ class GridMapEditor : public VBoxContainer { RID grid[3]; RID grid_instance[3]; + RID cursor_mesh; RID cursor_instance; RID selection_mesh; RID selection_instance; @@ -119,7 +144,12 @@ class GridMapEditor : public VBoxContainer { List<ClipboardItem> clipboard_items; + Color default_color; + Color erase_color; + Color pick_color; Ref<StandardMaterial3D> indicator_mat; + Ref<StandardMaterial3D> cursor_inner_mat; + Ref<StandardMaterial3D> cursor_outer_mat; Ref<StandardMaterial3D> inner_mat; Ref<StandardMaterial3D> outer_mat; Ref<StandardMaterial3D> selection_floor_mat; @@ -196,6 +226,7 @@ class GridMapEditor : public VBoxContainer { void _item_selected_cbk(int idx); void _update_cursor_transform(); void _update_cursor_instance(); + void _on_tool_mode_changed(); void _update_theme(); void _text_changed(const String &p_text); @@ -208,6 +239,7 @@ class GridMapEditor : public VBoxContainer { void _set_clipboard_data(); void _update_paste_indicator(); void _do_paste(); + void _show_viewports_transform_gizmo(bool p_value); void _update_selection_transform(); void _validate_selection(); void _set_selection(bool p_active, const Vector3 &p_begin = Vector3(), const Vector3 &p_end = Vector3()); @@ -238,9 +270,7 @@ class GridMapEditorPlugin : public EditorPlugin { GDCLASS(GridMapEditorPlugin, EditorPlugin); GridMapEditor *grid_map_editor = nullptr; - -protected: - void _notification(int p_what); + Button *panel_button = nullptr; public: virtual EditorPlugin::AfterGUIInput forward_3d_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) override { return grid_map_editor->forward_spatial_input_event(p_camera, p_event); } diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 71171be3f1..0588ba034a 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -801,8 +801,8 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) { if (!g.navigation_debug_edge_connections_instance.is_valid()) { g.navigation_debug_edge_connections_instance = RenderingServer::get_singleton()->instance_create(); } - if (!g.navigation_debug_edge_connections_mesh.is_valid()) { - g.navigation_debug_edge_connections_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + if (g.navigation_debug_edge_connections_mesh.is_null()) { + g.navigation_debug_edge_connections_mesh.instantiate(); } _update_octant_navigation_debug_edge_connections_mesh(p_key); @@ -1386,8 +1386,8 @@ void GridMap::_update_octant_navigation_debug_edge_connections_mesh(const Octant g.navigation_debug_edge_connections_instance = RenderingServer::get_singleton()->instance_create(); } - if (!g.navigation_debug_edge_connections_mesh.is_valid()) { - g.navigation_debug_edge_connections_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + if (g.navigation_debug_edge_connections_mesh.is_null()) { + g.navigation_debug_edge_connections_mesh.instantiate(); } g.navigation_debug_edge_connections_mesh->clear_surfaces(); diff --git a/modules/mbedtls/stream_peer_mbedtls.cpp b/modules/mbedtls/stream_peer_mbedtls.cpp index b4200410fb..3af66f6d83 100644 --- a/modules/mbedtls/stream_peer_mbedtls.cpp +++ b/modules/mbedtls/stream_peer_mbedtls.cpp @@ -166,21 +166,24 @@ Error StreamPeerMbedTLS::put_partial_data(const uint8_t *p_data, int p_bytes, in return OK; } - int ret = mbedtls_ssl_write(tls_ctx->get_context(), p_data, p_bytes); - if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { - // Non blocking IO - ret = 0; - } else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { - // Clean close - disconnect_from_stream(); - return ERR_FILE_EOF; - } else if (ret <= 0) { - TLSContextMbedTLS::print_mbedtls_error(ret); - disconnect_from_stream(); - return ERR_CONNECTION_ERROR; - } + do { + int ret = mbedtls_ssl_write(tls_ctx->get_context(), &p_data[r_sent], p_bytes - r_sent); + if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + // Non blocking IO. + break; + } else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { + // Clean close + disconnect_from_stream(); + return ERR_FILE_EOF; + } else if (ret <= 0) { + TLSContextMbedTLS::print_mbedtls_error(ret); + disconnect_from_stream(); + return ERR_CONNECTION_ERROR; + } + r_sent += ret; + + } while (r_sent < p_bytes); - r_sent = ret; return OK; } @@ -209,20 +212,25 @@ Error StreamPeerMbedTLS::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r r_received = 0; - int ret = mbedtls_ssl_read(tls_ctx->get_context(), p_buffer, p_bytes); - if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { - ret = 0; // non blocking io - } else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { - // Clean close - disconnect_from_stream(); - return ERR_FILE_EOF; - } else if (ret <= 0) { - TLSContextMbedTLS::print_mbedtls_error(ret); - disconnect_from_stream(); - return ERR_CONNECTION_ERROR; - } + do { + int ret = mbedtls_ssl_read(tls_ctx->get_context(), &p_buffer[r_received], p_bytes - r_received); + if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + // Non blocking IO. + break; + } else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { + // Clean close + disconnect_from_stream(); + return ERR_FILE_EOF; + } else if (ret <= 0) { + TLSContextMbedTLS::print_mbedtls_error(ret); + disconnect_from_stream(); + return ERR_CONNECTION_ERROR; + } + + r_received += ret; + + } while (r_received < p_bytes); - r_received = ret; return OK; } diff --git a/modules/minimp3/resource_importer_mp3.cpp b/modules/minimp3/resource_importer_mp3.cpp index e4b54ef050..f1f0a771ad 100644 --- a/modules/minimp3/resource_importer_mp3.cpp +++ b/modules/minimp3/resource_importer_mp3.cpp @@ -115,7 +115,7 @@ Ref<AudioStreamMP3> ResourceImporterMP3::import_mp3(const String &p_path) { return mp3_stream; } -Error ResourceImporterMP3::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterMP3::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { bool loop = p_options["loop"]; float loop_offset = p_options["loop_offset"]; double bpm = p_options["bpm"]; diff --git a/modules/minimp3/resource_importer_mp3.h b/modules/minimp3/resource_importer_mp3.h index 037756328f..35cc761eb4 100644 --- a/modules/minimp3/resource_importer_mp3.h +++ b/modules/minimp3/resource_importer_mp3.h @@ -57,7 +57,7 @@ public: #endif static Ref<AudioStreamMP3> import_mp3(const String &p_path); - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; virtual bool can_import_threaded() const override { return true; } diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 6ae9ce56c6..380b401683 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -2826,7 +2826,7 @@ Ref<Resource> ResourceFormatLoaderCSharpScript::load(const String &p_path, const GDMonoCache::managed_callbacks.ScriptManagerBridge_GetOrCreateScriptBridgeForPath(&p_path, &scr); ERR_FAIL_COND_V_MSG(scr.is_null(), Ref<Resource>(), "Could not create C# script '" + real_path + "'."); } else { - scr = Ref<CSharpScript>(memnew(CSharpScript)); + scr.instantiate(); } #if defined(DEBUG_ENABLED) || defined(TOOLS_ENABLED) diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs index f54058b0d9..5af859c06b 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/EventSignals_ScriptSignals.generated.cs @@ -32,9 +32,9 @@ partial class EventSignals add => backing_MySignal += value; remove => backing_MySignal -= value; } - protected void EmitSignalMySignal(string str, int num) + protected void EmitSignalMySignal(string @str, int @num) { - EmitSignal(SignalName.MySignal, str, num); + EmitSignal(SignalName.MySignal, @str, @num); } /// <inheritdoc/> [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs index 702c50d461..c7a7415851 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs @@ -295,7 +295,7 @@ namespace Godot.SourceGenerators for (int i = 0; i < paramCount; i++) { var paramSymbol = invokeMethodSymbol.Parameters[i]; - source.Append($"{paramSymbol.Type.FullQualifiedNameIncludeGlobal()} {paramSymbol.Name}"); + source.Append($"{paramSymbol.Type.FullQualifiedNameIncludeGlobal()} @{paramSymbol.Name}"); if (i < paramCount - 1) { source.Append(", "); @@ -310,11 +310,11 @@ namespace Godot.SourceGenerators if (paramSymbol.Type.TypeKind == TypeKind.Enum) { var underlyingType = ((INamedTypeSymbol)paramSymbol.Type).EnumUnderlyingType; - source.Append($", ({underlyingType.FullQualifiedNameIncludeGlobal()}){paramSymbol.Name}"); + source.Append($", ({underlyingType.FullQualifiedNameIncludeGlobal()})@{paramSymbol.Name}"); continue; } - source.Append($", {paramSymbol.Name}"); + source.Append($", @{paramSymbol.Name}"); } source.Append(");\n"); source.Append(" }\n"); diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index 788b46ab9a..74e04b46a1 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -177,7 +177,7 @@ namespace GodotTools private static readonly string[] VsCodeNames = { - "code", "code-oss", "vscode", "vscode-oss", "visual-studio-code", "visual-studio-code-oss" + "code", "code-oss", "vscode", "vscode-oss", "visual-studio-code", "visual-studio-code-oss", "codium" }; [UsedImplicitly] @@ -330,7 +330,7 @@ namespace GodotTools args.Add("-b"); args.Add(vscodeBundleId); - // The reusing of existing windows made by the 'open' command might not choose a wubdiw that is + // The reusing of existing windows made by the 'open' command might not choose a window that is // editing our folder. It's better to ask for a new window and let VSCode do the window management. args.Add("-n"); @@ -339,6 +339,28 @@ namespace GodotTools args.Add("--args"); } + + // Try VSCodium as a fallback if Visual Studio Code can't be found. + if (!macOSAppBundleInstalled) + { + const string VscodiumBundleId = "com.vscodium.codium"; + macOSAppBundleInstalled = Internal.IsMacOSAppBundleInstalled(VscodiumBundleId); + + if (macOSAppBundleInstalled) + { + args.Add("-b"); + args.Add(VscodiumBundleId); + + // The reusing of existing windows made by the 'open' command might not choose a window that is + // editing our folder. It's better to ask for a new window and let VSCode do the window management. + args.Add("-n"); + + // The open process must wait until the application finishes (which is instant in VSCode's case) + args.Add("--wait-apps"); + + args.Add("--args"); + } + } } args.Add(Path.GetDirectoryName(GodotSharpDirs.ProjectSlnPath)!); @@ -361,7 +383,7 @@ namespace GodotTools { if (!macOSAppBundleInstalled && string.IsNullOrEmpty(_vsCodePath)) { - GD.PushError("Cannot find code editor: VSCode"); + GD.PushError("Cannot find code editor: Visual Studio Code or VSCodium"); return Error.FileNotFound; } @@ -371,7 +393,7 @@ namespace GodotTools { if (string.IsNullOrEmpty(_vsCodePath)) { - GD.PushError("Cannot find code editor: VSCode"); + GD.PushError("Cannot find code editor: Visual Studio Code or VSCodium"); return Error.FileNotFound; } @@ -384,7 +406,7 @@ namespace GodotTools } catch (Exception e) { - GD.PushError($"Error when trying to run code editor: VSCode. Exception message: '{e.Message}'"); + GD.PushError($"Error when trying to run code editor: Visual Studio Code or VSCodium. Exception message: '{e.Message}'"); } break; @@ -550,7 +572,7 @@ namespace GodotTools { settingsHintStr += $",Visual Studio:{(int)ExternalEditorId.VisualStudio}" + $",MonoDevelop:{(int)ExternalEditorId.MonoDevelop}" + - $",Visual Studio Code:{(int)ExternalEditorId.VsCode}" + + $",Visual Studio Code and VSCodium:{(int)ExternalEditorId.VsCode}" + $",JetBrains Rider and Fleet:{(int)ExternalEditorId.Rider}" + $",Custom:{(int)ExternalEditorId.CustomEditor}"; } @@ -558,14 +580,14 @@ namespace GodotTools { settingsHintStr += $",Visual Studio:{(int)ExternalEditorId.VisualStudioForMac}" + $",MonoDevelop:{(int)ExternalEditorId.MonoDevelop}" + - $",Visual Studio Code:{(int)ExternalEditorId.VsCode}" + + $",Visual Studio Code and VSCodium:{(int)ExternalEditorId.VsCode}" + $",JetBrains Rider and Fleet:{(int)ExternalEditorId.Rider}" + $",Custom:{(int)ExternalEditorId.CustomEditor}"; } else if (OS.IsUnixLike) { settingsHintStr += $",MonoDevelop:{(int)ExternalEditorId.MonoDevelop}" + - $",Visual Studio Code:{(int)ExternalEditorId.VsCode}" + + $",Visual Studio Code and VSCodium:{(int)ExternalEditorId.VsCode}" + $",JetBrains Rider and Fleet:{(int)ExternalEditorId.Rider}" + $",Custom:{(int)ExternalEditorId.CustomEditor}"; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs index dc151e2c3e..222ded6895 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs @@ -534,7 +534,10 @@ namespace Godot.NativeInterop [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Callable ConvertToCallable(in godot_variant p_var) - => Marshaling.ConvertCallableToManaged(ConvertToNativeCallable(p_var)); + { + using var callable = ConvertToNativeCallable(p_var); + return Marshaling.ConvertCallableToManaged(callable); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static godot_signal ConvertToNativeSignal(in godot_variant p_var) @@ -542,7 +545,10 @@ namespace Godot.NativeInterop [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Signal ConvertToSignal(in godot_variant p_var) - => Marshaling.ConvertSignalToManaged(ConvertToNativeSignal(p_var)); + { + using var signal = ConvertToNativeSignal(p_var); + return Marshaling.ConvertSignalToManaged(signal); + } public static godot_array ConvertToNativeArray(in godot_variant p_var) => p_var.Type == Variant.Type.Array ? diff --git a/modules/multiplayer/scene_multiplayer.cpp b/modules/multiplayer/scene_multiplayer.cpp index e245101eeb..dde14034e6 100644 --- a/modules/multiplayer/scene_multiplayer.cpp +++ b/modules/multiplayer/scene_multiplayer.cpp @@ -684,9 +684,9 @@ void SceneMultiplayer::_bind_methods() { SceneMultiplayer::SceneMultiplayer() { relay_buffer.instantiate(); - cache = Ref<SceneCacheInterface>(memnew(SceneCacheInterface(this))); - replicator = Ref<SceneReplicationInterface>(memnew(SceneReplicationInterface(this, cache.ptr()))); - rpc = Ref<SceneRPCInterface>(memnew(SceneRPCInterface(this, cache.ptr(), replicator.ptr()))); + cache.instantiate(this); + replicator.instantiate(this, cache.ptr()); + rpc.instantiate(this, cache.ptr(), replicator.ptr()); set_multiplayer_peer(Ref<OfflineMultiplayerPeer>(memnew(OfflineMultiplayerPeer))); } diff --git a/modules/multiplayer/scene_rpc_interface.cpp b/modules/multiplayer/scene_rpc_interface.cpp index 0938d7ef99..b5f3889268 100644 --- a/modules/multiplayer/scene_rpc_interface.cpp +++ b/modules/multiplayer/scene_rpc_interface.cpp @@ -73,16 +73,6 @@ int get_packet_len(uint32_t p_node_target, int p_packet_len) { } } -bool SceneRPCInterface::_sort_rpc_names(const Variant &p_l, const Variant &p_r) { - if (likely(p_l.is_string() && p_r.is_string())) { - return p_l.operator String() < p_r.operator String(); - } - bool valid = false; - Variant res; - Variant::evaluate(Variant::OP_LESS, p_l, p_r, res, valid); - return valid ? res.operator bool() : false; -} - void SceneRPCInterface::_parse_rpc_config(const Variant &p_config, bool p_for_node, RPCConfigCache &r_cache) { if (p_config.get_type() == Variant::NIL) { return; @@ -90,7 +80,7 @@ void SceneRPCInterface::_parse_rpc_config(const Variant &p_config, bool p_for_no ERR_FAIL_COND(p_config.get_type() != Variant::DICTIONARY); const Dictionary config = p_config; Array names = config.keys(); - names.sort_custom(callable_mp_static(&SceneRPCInterface::_sort_rpc_names)); // Ensure ID order + names.sort_custom(callable_mp_static(&StringLikeVariantOrder::compare)); // Ensure ID order for (int i = 0; i < names.size(); i++) { ERR_CONTINUE(!names[i].is_string()); String name = names[i].operator String(); diff --git a/modules/multiplayer/scene_rpc_interface.h b/modules/multiplayer/scene_rpc_interface.h index 852cef7830..5c9b66d5f5 100644 --- a/modules/multiplayer/scene_rpc_interface.h +++ b/modules/multiplayer/scene_rpc_interface.h @@ -91,8 +91,6 @@ private: #endif protected: - static bool _sort_rpc_names(const Variant &p_l, const Variant &p_r); - void _process_rpc(Node *p_node, const uint16_t p_rpc_method_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset); void _send_rpc(Node *p_from, int p_to, uint16_t p_rpc_id, const RPCConfig &p_config, const StringName &p_name, const Variant **p_arg, int p_argcount); diff --git a/modules/navigation/2d/nav_mesh_generator_2d.cpp b/modules/navigation/2d/nav_mesh_generator_2d.cpp index 16cef0dd34..c996c9e935 100644 --- a/modules/navigation/2d/nav_mesh_generator_2d.cpp +++ b/modules/navigation/2d/nav_mesh_generator_2d.cpp @@ -691,11 +691,15 @@ void NavMeshGenerator2D::generator_parse_navigationobstacle_node(const Ref<Navig return; } - const Transform2D node_xform = p_source_geometry_data->root_node_transform * Transform2D(0.0, obstacle->get_global_position()); - + const Vector2 safe_scale = obstacle->get_global_scale().abs().maxf(0.001); const float obstacle_radius = obstacle->get_radius(); if (obstacle_radius > 0.0) { + // Radius defined obstacle should be uniformly scaled from obstacle basis max scale axis. + const float scaling_max_value = safe_scale[safe_scale.max_axis_index()]; + const Vector2 uniform_max_scale = Vector2(scaling_max_value, scaling_max_value); + const Transform2D obstacle_circle_transform = p_source_geometry_data->root_node_transform * Transform2D(obstacle->get_global_rotation(), uniform_max_scale, 0.0, obstacle->get_global_position()); + Vector<Vector2> obstruction_circle_vertices; // The point of this is that the moving obstacle can make a simple hole in the navigation mesh and affect the pathfinding. @@ -709,12 +713,15 @@ void NavMeshGenerator2D::generator_parse_navigationobstacle_node(const Ref<Navig for (int i = 0; i < circle_points; i++) { const float angle = i * circle_point_step; - circle_vertices_ptrw[i] = node_xform.xform(Vector2(Math::cos(angle) * obstacle_radius, Math::sin(angle) * obstacle_radius)); + circle_vertices_ptrw[i] = obstacle_circle_transform.xform(Vector2(Math::cos(angle) * obstacle_radius, Math::sin(angle) * obstacle_radius)); } p_source_geometry_data->add_projected_obstruction(obstruction_circle_vertices, obstacle->get_carve_navigation_mesh()); } + // Obstacles are projected to the xz-plane, so only rotation around the y-axis can be taken into account. + const Transform2D node_xform = p_source_geometry_data->root_node_transform * obstacle->get_global_transform(); + const Vector<Vector2> &obstacle_vertices = obstacle->get_vertices(); if (obstacle_vertices.is_empty()) { @@ -760,16 +767,14 @@ void NavMeshGenerator2D::generator_parse_source_geometry_data(Ref<NavigationPoly static void generator_recursive_process_polytree_items(List<TPPLPoly> &p_tppl_in_polygon, const Clipper2Lib::PolyPathD *p_polypath_item) { using namespace Clipper2Lib; - Vector<Vector2> polygon_vertices; + TPPLPoly tp; + int size = p_polypath_item->Polygon().size(); + tp.Init(size); + int j = 0; for (const PointD &polypath_point : p_polypath_item->Polygon()) { - polygon_vertices.push_back(Vector2(static_cast<real_t>(polypath_point.x), static_cast<real_t>(polypath_point.y))); - } - - TPPLPoly tp; - tp.Init(polygon_vertices.size()); - for (int j = 0; j < polygon_vertices.size(); j++) { - tp[j] = polygon_vertices[j]; + tp[j] = Vector2(static_cast<real_t>(polypath_point.x), static_cast<real_t>(polypath_point.y)); + ++j; } if (p_polypath_item->IsHole()) { @@ -842,87 +847,79 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation return; } - if (p_navigation_mesh->get_outline_count() == 0 && !p_source_geometry_data->has_data()) { - return; - } - - int outline_count = p_navigation_mesh->get_outline_count(); - - Vector<Vector<Vector2>> traversable_outlines; - Vector<Vector<Vector2>> obstruction_outlines; - Vector<NavigationMeshSourceGeometryData2D::ProjectedObstruction> projected_obstructions; - - p_source_geometry_data->get_data( - traversable_outlines, - obstruction_outlines, - projected_obstructions); - - if (outline_count == 0 && traversable_outlines.size() == 0) { - return; - } - using namespace Clipper2Lib; - PathsD traversable_polygon_paths; PathsD obstruction_polygon_paths; + int obstruction_polygon_path_size = 0; + { + RWLockRead read_lock(p_source_geometry_data->geometry_rwlock); - traversable_polygon_paths.reserve(outline_count + traversable_outlines.size()); - obstruction_polygon_paths.reserve(obstruction_outlines.size()); + const Vector<Vector<Vector2>> &traversable_outlines = p_source_geometry_data->traversable_outlines; + int outline_count = p_navigation_mesh->get_outline_count(); - for (int i = 0; i < outline_count; i++) { - const Vector<Vector2> &traversable_outline = p_navigation_mesh->get_outline(i); - PathD subject_path; - subject_path.reserve(traversable_outline.size()); - for (const Vector2 &traversable_point : traversable_outline) { - const PointD &point = PointD(traversable_point.x, traversable_point.y); - subject_path.push_back(point); + if (outline_count == 0 && (!p_source_geometry_data->has_data() || (traversable_outlines.is_empty()))) { + return; } - traversable_polygon_paths.push_back(subject_path); - } - for (const Vector<Vector2> &traversable_outline : traversable_outlines) { - PathD subject_path; - subject_path.reserve(traversable_outline.size()); - for (const Vector2 &traversable_point : traversable_outline) { - const PointD &point = PointD(traversable_point.x, traversable_point.y); - subject_path.push_back(point); - } - traversable_polygon_paths.push_back(subject_path); - } + const Vector<Vector<Vector2>> &obstruction_outlines = p_source_geometry_data->obstruction_outlines; + const Vector<NavigationMeshSourceGeometryData2D::ProjectedObstruction> &projected_obstructions = p_source_geometry_data->_projected_obstructions; + + traversable_polygon_paths.reserve(outline_count + traversable_outlines.size()); + obstruction_polygon_paths.reserve(obstruction_outlines.size()); - for (const Vector<Vector2> &obstruction_outline : obstruction_outlines) { - PathD clip_path; - clip_path.reserve(obstruction_outline.size()); - for (const Vector2 &obstruction_point : obstruction_outline) { - const PointD &point = PointD(obstruction_point.x, obstruction_point.y); - clip_path.push_back(point); + for (int i = 0; i < outline_count; i++) { + const Vector<Vector2> &traversable_outline = p_navigation_mesh->get_outline(i); + PathD subject_path; + subject_path.reserve(traversable_outline.size()); + for (const Vector2 &traversable_point : traversable_outline) { + subject_path.emplace_back(traversable_point.x, traversable_point.y); + } + traversable_polygon_paths.push_back(std::move(subject_path)); } - obstruction_polygon_paths.push_back(clip_path); - } - if (!projected_obstructions.is_empty()) { - for (const NavigationMeshSourceGeometryData2D::ProjectedObstruction &projected_obstruction : projected_obstructions) { - if (projected_obstruction.carve) { - continue; + for (const Vector<Vector2> &traversable_outline : traversable_outlines) { + PathD subject_path; + subject_path.reserve(traversable_outline.size()); + for (const Vector2 &traversable_point : traversable_outline) { + subject_path.emplace_back(traversable_point.x, traversable_point.y); } - if (projected_obstruction.vertices.is_empty() || projected_obstruction.vertices.size() % 2 != 0) { - continue; + traversable_polygon_paths.push_back(std::move(subject_path)); + } + + if (!projected_obstructions.is_empty()) { + for (const NavigationMeshSourceGeometryData2D::ProjectedObstruction &projected_obstruction : projected_obstructions) { + if (projected_obstruction.carve) { + continue; + } + if (projected_obstruction.vertices.is_empty() || projected_obstruction.vertices.size() % 2 != 0) { + continue; + } + + PathD clip_path; + clip_path.reserve(projected_obstruction.vertices.size() / 2); + for (int i = 0; i < projected_obstruction.vertices.size() / 2; i++) { + clip_path.emplace_back(projected_obstruction.vertices[i * 2], projected_obstruction.vertices[i * 2 + 1]); + } + if (!IsPositive(clip_path)) { + std::reverse(clip_path.begin(), clip_path.end()); + } + obstruction_polygon_paths.push_back(std::move(clip_path)); } + } + obstruction_polygon_path_size = obstruction_polygon_paths.size(); + for (const Vector<Vector2> &obstruction_outline : obstruction_outlines) { PathD clip_path; - clip_path.reserve(projected_obstruction.vertices.size() / 2); - for (int i = 0; i < projected_obstruction.vertices.size() / 2; i++) { - const PointD &point = PointD(projected_obstruction.vertices[i * 2], projected_obstruction.vertices[i * 2 + 1]); - clip_path.push_back(point); - } - if (!IsPositive(clip_path)) { - std::reverse(clip_path.begin(), clip_path.end()); + clip_path.reserve(obstruction_outline.size()); + for (const Vector2 &obstruction_point : obstruction_outline) { + clip_path.emplace_back(obstruction_point.x, obstruction_point.y); } - obstruction_polygon_paths.push_back(clip_path); + obstruction_polygon_paths.push_back(std::move(clip_path)); } } Rect2 baking_rect = p_navigation_mesh->get_baking_rect(); + PathsD area_obstruction_polygon_paths; if (baking_rect.has_area()) { Vector2 baking_rect_offset = p_navigation_mesh->get_baking_rect_offset(); @@ -934,48 +931,27 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation RectD clipper_rect = RectD(rect_begin_x, rect_begin_y, rect_end_x, rect_end_y); traversable_polygon_paths = RectClip(clipper_rect, traversable_polygon_paths); - obstruction_polygon_paths = RectClip(clipper_rect, obstruction_polygon_paths); + area_obstruction_polygon_paths = RectClip(clipper_rect, obstruction_polygon_paths); + } else { + area_obstruction_polygon_paths = obstruction_polygon_paths; } - PathsD path_solution; - // first merge all traversable polygons according to user specified fill rule PathsD dummy_clip_path; traversable_polygon_paths = Union(traversable_polygon_paths, dummy_clip_path, FillRule::NonZero); // merge all obstruction polygons, don't allow holes for what is considered "solid" 2D geometry - obstruction_polygon_paths = Union(obstruction_polygon_paths, dummy_clip_path, FillRule::NonZero); + area_obstruction_polygon_paths = Union(area_obstruction_polygon_paths, dummy_clip_path, FillRule::NonZero); - path_solution = Difference(traversable_polygon_paths, obstruction_polygon_paths, FillRule::NonZero); + PathsD path_solution = Difference(traversable_polygon_paths, area_obstruction_polygon_paths, FillRule::NonZero); real_t agent_radius_offset = p_navigation_mesh->get_agent_radius(); if (agent_radius_offset > 0.0) { path_solution = InflatePaths(path_solution, -agent_radius_offset, JoinType::Miter, EndType::Polygon); } - if (!projected_obstructions.is_empty()) { - obstruction_polygon_paths.resize(0); - for (const NavigationMeshSourceGeometryData2D::ProjectedObstruction &projected_obstruction : projected_obstructions) { - if (!projected_obstruction.carve) { - continue; - } - if (projected_obstruction.vertices.is_empty() || projected_obstruction.vertices.size() % 2 != 0) { - continue; - } - - PathD clip_path; - clip_path.reserve(projected_obstruction.vertices.size() / 2); - for (int i = 0; i < projected_obstruction.vertices.size() / 2; i++) { - const PointD &point = PointD(projected_obstruction.vertices[i * 2], projected_obstruction.vertices[i * 2 + 1]); - clip_path.push_back(point); - } - if (!IsPositive(clip_path)) { - std::reverse(clip_path.begin(), clip_path.end()); - } - obstruction_polygon_paths.push_back(clip_path); - } - if (obstruction_polygon_paths.size() > 0) { - path_solution = Difference(path_solution, obstruction_polygon_paths, FillRule::NonZero); - } + if (obstruction_polygon_path_size > 0) { + obstruction_polygon_paths.resize(obstruction_polygon_path_size); + path_solution = Difference(path_solution, obstruction_polygon_paths, FillRule::NonZero); } //path_solution = RamerDouglasPeucker(path_solution, 0.025); // @@ -994,33 +970,11 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation path_solution = RectClip(clipper_rect, path_solution); } - Vector<Vector<Vector2>> new_baked_outlines; - - for (const PathD &scaled_path : path_solution) { - Vector<Vector2> polypath; - for (const PointD &scaled_point : scaled_path) { - polypath.push_back(Vector2(static_cast<real_t>(scaled_point.x), static_cast<real_t>(scaled_point.y))); - } - new_baked_outlines.push_back(polypath); - } - - if (new_baked_outlines.size() == 0) { + if (path_solution.size() == 0) { p_navigation_mesh->clear(); return; } - PathsD polygon_paths; - polygon_paths.reserve(new_baked_outlines.size()); - - for (const Vector<Vector2> &baked_outline : new_baked_outlines) { - PathD polygon_path; - for (const Vector2 &baked_outline_point : baked_outline) { - const PointD &point = PointD(baked_outline_point.x, baked_outline_point.y); - polygon_path.push_back(point); - } - polygon_paths.push_back(polygon_path); - } - ClipType clipper_cliptype = ClipType::Union; List<TPPLPoly> tppl_in_polygon, tppl_out_polygon; @@ -1028,7 +982,7 @@ void NavMeshGenerator2D::generator_bake_from_source_geometry_data(Ref<Navigation PolyTreeD polytree; ClipperD clipper_D; - clipper_D.AddSubject(polygon_paths); + clipper_D.AddSubject(path_solution); clipper_D.Execute(clipper_cliptype, FillRule::NonZero, polytree); for (size_t i = 0; i < polytree.Count(); i++) { diff --git a/modules/navigation/3d/nav_mesh_generator_3d.cpp b/modules/navigation/3d/nav_mesh_generator_3d.cpp index ce1551e584..3d0697a7cf 100644 --- a/modules/navigation/3d/nav_mesh_generator_3d.cpp +++ b/modules/navigation/3d/nav_mesh_generator_3d.cpp @@ -595,11 +595,17 @@ void NavMeshGenerator3D::generator_parse_navigationobstacle_node(const Ref<Navig return; } - const Transform3D node_xform = p_source_geometry_data->root_node_transform * Transform3D(Basis(), obstacle->get_global_position()); - + const float elevation = obstacle->get_global_position().y + p_source_geometry_data->root_node_transform.origin.y; + // Prevent non-positive scaling. + const Vector3 safe_scale = obstacle->get_global_basis().get_scale().abs().maxf(0.001); const float obstacle_radius = obstacle->get_radius(); if (obstacle_radius > 0.0) { + // Radius defined obstacle should be uniformly scaled from obstacle basis max scale axis. + const float scaling_max_value = safe_scale[safe_scale.max_axis_index()]; + const Vector3 uniform_max_scale = Vector3(scaling_max_value, scaling_max_value, scaling_max_value); + const Transform3D obstacle_circle_transform = p_source_geometry_data->root_node_transform * Transform3D(Basis().scaled(uniform_max_scale), obstacle->get_global_position()); + Vector<Vector3> obstruction_circle_vertices; // The point of this is that the moving obstacle can make a simple hole in the navigation mesh and affect the pathfinding. @@ -613,12 +619,15 @@ void NavMeshGenerator3D::generator_parse_navigationobstacle_node(const Ref<Navig for (int i = 0; i < circle_points; i++) { const float angle = i * circle_point_step; - circle_vertices_ptrw[i] = node_xform.xform(Vector3(Math::cos(angle) * obstacle_radius, 0.0, Math::sin(angle) * obstacle_radius)); + circle_vertices_ptrw[i] = obstacle_circle_transform.xform(Vector3(Math::cos(angle) * obstacle_radius, 0.0, Math::sin(angle) * obstacle_radius)); } - p_source_geometry_data->add_projected_obstruction(obstruction_circle_vertices, obstacle->get_global_position().y + p_source_geometry_data->root_node_transform.origin.y - obstacle_radius, obstacle_radius, obstacle->get_carve_navigation_mesh()); + p_source_geometry_data->add_projected_obstruction(obstruction_circle_vertices, elevation - obstacle_radius, scaling_max_value * obstacle_radius, obstacle->get_carve_navigation_mesh()); } + // Obstacles are projected to the xz-plane, so only rotation around the y-axis can be taken into account. + const Transform3D node_xform = p_source_geometry_data->root_node_transform * Transform3D(Basis().scaled(safe_scale).rotated(Vector3(0.0, 1.0, 0.0), obstacle->get_global_rotation().y), obstacle->get_global_position()); + const Vector<Vector3> &obstacle_vertices = obstacle->get_vertices(); if (obstacle_vertices.is_empty()) { @@ -635,7 +644,7 @@ void NavMeshGenerator3D::generator_parse_navigationobstacle_node(const Ref<Navig obstruction_shape_vertices_ptrw[i] = node_xform.xform(obstacle_vertices_ptr[i]); obstruction_shape_vertices_ptrw[i].y = 0.0; } - p_source_geometry_data->add_projected_obstruction(obstruction_shape_vertices, obstacle->get_global_position().y + p_source_geometry_data->root_node_transform.origin.y, obstacle->get_height(), obstacle->get_carve_navigation_mesh()); + p_source_geometry_data->add_projected_obstruction(obstruction_shape_vertices, elevation, safe_scale.y * obstacle->get_height(), obstacle->get_carve_navigation_mesh()); } void NavMeshGenerator3D::generator_parse_source_geometry_data(const Ref<NavigationMesh> &p_navigation_mesh, Ref<NavigationMeshSourceGeometryData3D> p_source_geometry_data, Node *p_root_node) { diff --git a/modules/noise/doc_classes/FastNoiseLite.xml b/modules/noise/doc_classes/FastNoiseLite.xml index 6f6a637893..e29581693b 100644 --- a/modules/noise/doc_classes/FastNoiseLite.xml +++ b/modules/noise/doc_classes/FastNoiseLite.xml @@ -118,7 +118,7 @@ Manhattan distance (taxicab metric) to the nearest point. </constant> <constant name="DISTANCE_HYBRID" value="3" enum="CellularDistanceFunction"> - Blend of [constant DISTANCE_EUCLIDEAN] and [constant DISTANCE_MANHATTAN] to give curved cell boundaries + Blend of [constant DISTANCE_EUCLIDEAN] and [constant DISTANCE_MANHATTAN] to give curved cell boundaries. </constant> <constant name="RETURN_CELL_VALUE" value="0" enum="CellularReturnType"> The cellular distance function will return the same value for all points within a cell. diff --git a/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml b/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml index 182fe32f9c..c174ee4d69 100644 --- a/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml +++ b/modules/openxr/doc_classes/OpenXRExtensionWrapperExtension.xml @@ -235,7 +235,7 @@ <return type="int" /> <param index="0" name="next_pointer" type="void*" /> <description> - Adds additional data structures when interogating OpenXR system abilities. + Adds additional data structures when querying OpenXR system abilities. </description> </method> <method name="_set_viewport_composition_layer_and_get_next_pointer" qualifiers="virtual"> diff --git a/modules/openxr/extensions/openxr_composition_layer_extension.cpp b/modules/openxr/extensions/openxr_composition_layer_extension.cpp index 2d29b8a82c..1e3490d1ed 100644 --- a/modules/openxr/extensions/openxr_composition_layer_extension.cpp +++ b/modules/openxr/extensions/openxr_composition_layer_extension.cpp @@ -281,7 +281,7 @@ void OpenXRViewportCompositionLayerProvider::create_android_surface() { composition_layer_extension->create_android_surface_swapchain(&info, &android_surface.swapchain, &surface); if (surface) { - android_surface.surface = Ref<JavaObject>(memnew(JavaObject(JavaClassWrapper::get_singleton()->wrap("android.view.Surface"), surface))); + android_surface.surface.instantiate(JavaClassWrapper::get_singleton()->wrap("android.view.Surface"), surface); } } #endif diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp index a6fd727290..1775541757 100644 --- a/modules/openxr/openxr_api.cpp +++ b/modules/openxr/openxr_api.cpp @@ -2036,8 +2036,9 @@ bool OpenXRAPI::poll_events() { if (local_floor_emulation.enabled) { local_floor_emulation.should_reset_floor_height = true; } - if (event->poseValid && xr_interface) { - xr_interface->on_pose_recentered(); + + if (xr_interface) { + xr_interface->on_reference_space_change_pending(); } } break; case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED: { diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp index 8e0c672e58..68e04694e3 100644 --- a/modules/openxr/openxr_interface.cpp +++ b/modules/openxr/openxr_interface.cpp @@ -1134,6 +1134,12 @@ void OpenXRInterface::process() { if (head.is_valid()) { head->set_pose("default", head_transform, head_linear_velocity, head_angular_velocity, head_confidence); } + + if (reference_stage_changing) { + // Now that we have updated tracking information in our updated reference space, trigger our pose recentered signal. + emit_signal(SNAME("pose_recentered")); + reference_stage_changing = false; + } } void OpenXRInterface::pre_render() { @@ -1315,8 +1321,8 @@ void OpenXRInterface::on_state_exiting() { emit_signal(SNAME("instance_exiting")); } -void OpenXRInterface::on_pose_recentered() { - emit_signal(SNAME("pose_recentered")); +void OpenXRInterface::on_reference_space_change_pending() { + reference_stage_changing = true; } void OpenXRInterface::on_refresh_rate_changes(float p_new_rate) { diff --git a/modules/openxr/openxr_interface.h b/modules/openxr/openxr_interface.h index f0ee0dc3c4..d1bf2aaf78 100644 --- a/modules/openxr/openxr_interface.h +++ b/modules/openxr/openxr_interface.h @@ -70,6 +70,7 @@ class OpenXRInterface : public XRInterface { private: OpenXRAPI *openxr_api = nullptr; bool initialized = false; + bool reference_stage_changing = false; XRInterface::TrackingStatus tracking_state; // At a minimum we need a tracker for our head @@ -207,7 +208,7 @@ public: void on_state_stopping(); void on_state_loss_pending(); void on_state_exiting(); - void on_pose_recentered(); + void on_reference_space_change_pending(); void on_refresh_rate_changes(float p_new_rate); void tracker_profile_changed(RID p_tracker, RID p_interaction_profile); diff --git a/modules/regex/doc_classes/RegEx.xml b/modules/regex/doc_classes/RegEx.xml index e12dc43b6f..66e7cd5a0b 100644 --- a/modules/regex/doc_classes/RegEx.xml +++ b/modules/regex/doc_classes/RegEx.xml @@ -34,14 +34,14 @@ print(result.get_string("digit")) # Would print 01 03 0 3f 42 [/codeblock] - [b]Example of splitting a string using a RegEx:[/b] + [b]Example:[/b] Split a string using a RegEx: [codeblock] var regex = RegEx.new() regex.compile("\\S+") # Negated whitespace character class. var results = [] for result in regex.search_all("One Two \n\tThree"): results.push_back(result.get_string()) - # The `results` array now contains "One", "Two", "Three". + # The `results` array now contains "One", "Two", and "Three". [/codeblock] [b]Note:[/b] Godot's regex implementation is based on the [url=https://www.pcre.org/]PCRE2[/url] library. You can view the full pattern reference [url=https://www.pcre.org/current/doc/html/pcre2pattern.html]here[/url]. [b]Tip:[/b] You can use [url=https://regexr.com/]Regexr[/url] to test regular expressions online. diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index 8b2c58acd5..372885b0b4 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -629,7 +629,7 @@ void VideoStreamPlaybackTheora::_streaming_thread(void *ud) { #endif VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() { - texture = Ref<ImageTexture>(memnew(ImageTexture)); + texture.instantiate(); #ifdef THEORA_USE_THREAD_STREAMING int rb_power = nearest_shift(RB_SIZE_KB * 1024); diff --git a/modules/vorbis/resource_importer_ogg_vorbis.cpp b/modules/vorbis/resource_importer_ogg_vorbis.cpp index 729a6f5561..a7423e2d7b 100644 --- a/modules/vorbis/resource_importer_ogg_vorbis.cpp +++ b/modules/vorbis/resource_importer_ogg_vorbis.cpp @@ -95,7 +95,7 @@ void ResourceImporterOggVorbis::show_advanced_options(const String &p_path) { } #endif -Error ResourceImporterOggVorbis::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { +Error ResourceImporterOggVorbis::import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { bool loop = p_options["loop"]; double loop_offset = p_options["loop_offset"]; double bpm = p_options["bpm"]; diff --git a/modules/vorbis/resource_importer_ogg_vorbis.h b/modules/vorbis/resource_importer_ogg_vorbis.h index f378b80694..a4e4441d82 100644 --- a/modules/vorbis/resource_importer_ogg_vorbis.h +++ b/modules/vorbis/resource_importer_ogg_vorbis.h @@ -63,7 +63,7 @@ public: virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override; virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; - virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; + virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override; virtual bool can_import_threaded() const override { return true; } diff --git a/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml b/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml index 0978e1fcee..b2e1cb345b 100644 --- a/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml +++ b/modules/websocket/doc_classes/WebSocketMultiplayerPeer.xml @@ -60,7 +60,7 @@ <member name="inbound_buffer_size" type="int" setter="set_inbound_buffer_size" getter="get_inbound_buffer_size" default="65535"> The inbound buffer size for connected peers. See [member WebSocketPeer.inbound_buffer_size] for more details. </member> - <member name="max_queued_packets" type="int" setter="set_max_queued_packets" getter="get_max_queued_packets" default="2048"> + <member name="max_queued_packets" type="int" setter="set_max_queued_packets" getter="get_max_queued_packets" default="4096"> The maximum number of queued packets for connected peers. See [member WebSocketPeer.max_queued_packets] for more details. </member> <member name="outbound_buffer_size" type="int" setter="set_outbound_buffer_size" getter="get_outbound_buffer_size" default="65535"> diff --git a/modules/websocket/doc_classes/WebSocketPeer.xml b/modules/websocket/doc_classes/WebSocketPeer.xml index 238dd30536..d329e21b88 100644 --- a/modules/websocket/doc_classes/WebSocketPeer.xml +++ b/modules/websocket/doc_classes/WebSocketPeer.xml @@ -155,10 +155,14 @@ The extra HTTP headers to be sent during the WebSocket handshake. [b]Note:[/b] Not supported in Web exports due to browsers' restrictions. </member> + <member name="heartbeat_interval" type="float" setter="set_heartbeat_interval" getter="get_heartbeat_interval" default="0.0"> + The interval (in seconds) at which the peer will automatically send WebSocket "ping" control frames. When set to [code]0[/code], no "ping" control frames will be sent. + [b]Note:[/b] Has no effect in Web exports due to browser restrictions. + </member> <member name="inbound_buffer_size" type="int" setter="set_inbound_buffer_size" getter="get_inbound_buffer_size" default="65535"> The size of the input buffer in bytes (roughly the maximum amount of memory that will be allocated for the inbound packets). </member> - <member name="max_queued_packets" type="int" setter="set_max_queued_packets" getter="get_max_queued_packets" default="2048"> + <member name="max_queued_packets" type="int" setter="set_max_queued_packets" getter="get_max_queued_packets" default="4096"> The maximum amount of packets that will be allowed in the queues (both inbound and outbound). </member> <member name="outbound_buffer_size" type="int" setter="set_outbound_buffer_size" getter="get_outbound_buffer_size" default="65535"> diff --git a/modules/websocket/packet_buffer.h b/modules/websocket/packet_buffer.h index f98ee12ef9..4ab0579912 100644 --- a/modules/websocket/packet_buffer.h +++ b/modules/websocket/packet_buffer.h @@ -104,6 +104,14 @@ public: return _queued; } + int payload_space_left() const { + return _payload.space_left(); + } + + int packets_space_left() const { + return _packets.size() - _queued; + } + void clear() { _payload.resize(0); _packets.resize(0); diff --git a/modules/websocket/websocket_peer.cpp b/modules/websocket/websocket_peer.cpp index 95a1a238e9..5c24b5d082 100644 --- a/modules/websocket/websocket_peer.cpp +++ b/modules/websocket/websocket_peer.cpp @@ -70,6 +70,9 @@ void WebSocketPeer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_max_queued_packets", "buffer_size"), &WebSocketPeer::set_max_queued_packets); ClassDB::bind_method(D_METHOD("get_max_queued_packets"), &WebSocketPeer::get_max_queued_packets); + ClassDB::bind_method(D_METHOD("set_heartbeat_interval", "interval"), &WebSocketPeer::set_heartbeat_interval); + ClassDB::bind_method(D_METHOD("get_heartbeat_interval"), &WebSocketPeer::get_heartbeat_interval); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "supported_protocols"), "set_supported_protocols", "get_supported_protocols"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "handshake_headers"), "set_handshake_headers", "get_handshake_headers"); @@ -78,6 +81,8 @@ void WebSocketPeer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "max_queued_packets"), "set_max_queued_packets", "get_max_queued_packets"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "heartbeat_interval"), "set_heartbeat_interval", "get_heartbeat_interval"); + BIND_ENUM_CONSTANT(WRITE_MODE_TEXT); BIND_ENUM_CONSTANT(WRITE_MODE_BINARY); @@ -151,3 +156,12 @@ void WebSocketPeer::set_max_queued_packets(int p_max_queued_packets) { int WebSocketPeer::get_max_queued_packets() const { return max_queued_packets; } + +double WebSocketPeer::get_heartbeat_interval() const { + return heartbeat_interval_msec / 1000.0; +} + +void WebSocketPeer::set_heartbeat_interval(double p_interval) { + ERR_FAIL_COND(p_interval < 0); + heartbeat_interval_msec = p_interval * 1000.0; +} diff --git a/modules/websocket/websocket_peer.h b/modules/websocket/websocket_peer.h index ef0197cf6c..4854122471 100644 --- a/modules/websocket/websocket_peer.h +++ b/modules/websocket/websocket_peer.h @@ -71,7 +71,8 @@ protected: int outbound_buffer_size = DEFAULT_BUFFER_SIZE; int inbound_buffer_size = DEFAULT_BUFFER_SIZE; - int max_queued_packets = 2048; + int max_queued_packets = 4096; + uint64_t heartbeat_interval_msec = 0; public: static WebSocketPeer *create(bool p_notify_postinitialize = true) { @@ -117,6 +118,9 @@ public: void set_max_queued_packets(int p_max_queued_packets); int get_max_queued_packets() const; + double get_heartbeat_interval() const; + void set_heartbeat_interval(double p_interval); + WebSocketPeer(); ~WebSocketPeer(); }; diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp index 0c0a046805..81e5673583 100644 --- a/modules/websocket/wsl_peer.cpp +++ b/modules/websocket/wsl_peer.cpp @@ -295,6 +295,7 @@ Error WSLPeer::_do_server_handshake() { resolver.stop(); // Response sent, initialize wslay context. wslay_event_context_server_init(&wsl_ctx, &_wsl_callbacks, this); + wslay_event_config_set_no_buffering(wsl_ctx, 1); wslay_event_config_set_max_recv_msg_length(wsl_ctx, inbound_buffer_size); in_buffer.resize(nearest_shift(inbound_buffer_size), max_queued_packets); packet_buffer.resize(inbound_buffer_size); @@ -403,6 +404,7 @@ void WSLPeer::_do_client_handshake() { ERR_FAIL_MSG("Invalid response headers."); } wslay_event_context_client_init(&wsl_ctx, &_wsl_callbacks, this); + wslay_event_config_set_no_buffering(wsl_ctx, 1); wslay_event_config_set_max_recv_msg_length(wsl_ctx, inbound_buffer_size); in_buffer.resize(nearest_shift(inbound_buffer_size), max_queued_packets); packet_buffer.resize(inbound_buffer_size); @@ -568,8 +570,15 @@ ssize_t WSLPeer::_wsl_recv_callback(wslay_event_context_ptr ctx, uint8_t *data, wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE); return -1; } + // Make sure we don't read more than what our buffer can hold. + size_t buffer_limit = MIN(peer->in_buffer.payload_space_left(), peer->in_buffer.packets_space_left() * 2); // The minimum size of a websocket message is 2 bytes. + size_t to_read = MIN(len, buffer_limit); + if (to_read == 0) { + wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK); + return -1; + } int read = 0; - Error err = conn->get_partial_data(data, len, read); + Error err = conn->get_partial_data(data, to_read, read); if (err != OK) { print_verbose("Websocket get data error: " + itos(err) + ", read (should be 0!): " + itos(read)); wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE); @@ -582,6 +591,37 @@ ssize_t WSLPeer::_wsl_recv_callback(wslay_event_context_ptr ctx, uint8_t *data, return read; } +void WSLPeer::_wsl_recv_start_callback(wslay_event_context_ptr ctx, const struct wslay_event_on_frame_recv_start_arg *arg, void *user_data) { + WSLPeer *peer = (WSLPeer *)user_data; + uint8_t op = arg->opcode; + if (op == WSLAY_TEXT_FRAME || op == WSLAY_BINARY_FRAME) { + // Get ready to process a data package. + PendingMessage &pm = peer->pending_message; + pm.opcode = op; + pm.payload_size = arg->payload_length; + } +} + +void WSLPeer::_wsl_frame_recv_chunk_callback(wslay_event_context_ptr ctx, const struct wslay_event_on_frame_recv_chunk_arg *arg, void *user_data) { + WSLPeer *peer = (WSLPeer *)user_data; + PendingMessage &pm = peer->pending_message; + if (pm.opcode != 0) { + // Only write the payload. + peer->in_buffer.write_packet(arg->data, arg->data_length, nullptr); + } +} + +void WSLPeer::_wsl_frame_recv_end_callback(wslay_event_context_ptr ctx, void *user_data) { + WSLPeer *peer = (WSLPeer *)user_data; + PendingMessage &pm = peer->pending_message; + if (pm.opcode != 0) { + // Only write the packet (since it's now completed). + uint8_t is_string = pm.opcode == WSLAY_TEXT_FRAME ? 1 : 0; + peer->in_buffer.write_packet(nullptr, pm.payload_size, &is_string); + pm.clear(); + } +} + ssize_t WSLPeer::_wsl_send_callback(wslay_event_context_ptr ctx, const uint8_t *data, size_t len, int flags, void *user_data) { WSLPeer *peer = (WSLPeer *)user_data; Ref<StreamPeer> conn = peer->connection; @@ -627,25 +667,19 @@ void WSLPeer::_wsl_msg_recv_callback(wslay_event_context_ptr ctx, const struct w return; } - if (peer->ready_state == STATE_CLOSING) { - return; - } - - if (op == WSLAY_TEXT_FRAME || op == WSLAY_BINARY_FRAME) { - // Message. - uint8_t is_string = arg->opcode == WSLAY_TEXT_FRAME ? 1 : 0; - peer->in_buffer.write_packet(arg->msg, arg->msg_length, &is_string); + if (op == WSLAY_PONG) { + peer->heartbeat_waiting = false; } - // Ping or pong. + // Ping, or message (already parsed in chunks). } wslay_event_callbacks WSLPeer::_wsl_callbacks = { _wsl_recv_callback, _wsl_send_callback, _wsl_genmask_callback, - nullptr, /* on_frame_recv_start_callback */ - nullptr, /* on_frame_recv_callback */ - nullptr, /* on_frame_recv_end_callback */ + _wsl_recv_start_callback, + _wsl_frame_recv_chunk_callback, + _wsl_frame_recv_end_callback, _wsl_msg_recv_callback }; @@ -680,7 +714,31 @@ void WSLPeer::poll() { if (ready_state == STATE_OPEN || ready_state == STATE_CLOSING) { ERR_FAIL_NULL(wsl_ctx); + uint64_t ticks = OS::get_singleton()->get_ticks_msec(); int err = 0; + if (heartbeat_interval_msec != 0 && ticks - last_heartbeat > heartbeat_interval_msec && ready_state == STATE_OPEN) { + if (heartbeat_waiting) { + wslay_event_context_free(wsl_ctx); + wsl_ctx = nullptr; + close(-1); + return; + } + heartbeat_waiting = true; + struct wslay_event_msg msg; + msg.opcode = WSLAY_PING; + msg.msg = nullptr; + msg.msg_length = 0; + err = wslay_event_queue_msg(wsl_ctx, &msg); + if (err == 0) { + last_heartbeat = ticks; + } else { + print_verbose("Websocket (wslay) failed to send ping: " + itos(err)); + wslay_event_context_free(wsl_ctx); + wsl_ctx = nullptr; + close(-1); + return; + } + } if ((err = wslay_event_recv(wsl_ctx)) != 0 || (err = wslay_event_send(wsl_ctx)) != 0) { // Error close. print_verbose("Websocket (wslay) poll error: " + itos(err)); @@ -689,12 +747,37 @@ void WSLPeer::poll() { close(-1); return; } - if (wslay_event_get_close_sent(wsl_ctx) && wslay_event_get_close_received(wsl_ctx)) { - // Clean close. - wslay_event_context_free(wsl_ctx); - wsl_ctx = nullptr; - close(-1); - return; + if (wslay_event_get_close_sent(wsl_ctx)) { + if (wslay_event_get_close_received(wsl_ctx)) { + // Clean close. + wslay_event_context_free(wsl_ctx); + wsl_ctx = nullptr; + close(-1); + return; + } else if (!wslay_event_get_read_enabled(wsl_ctx)) { + // Some protocol error caused wslay to stop processing incoming events, we'll never receive a close from the other peer. + close_code = wslay_event_get_status_code_sent(wsl_ctx); + switch (close_code) { + case WSLAY_CODE_MESSAGE_TOO_BIG: + close_reason = "Message too big"; + break; + case WSLAY_CODE_PROTOCOL_ERROR: + close_reason = "Protocol error"; + break; + case WSLAY_CODE_ABNORMAL_CLOSURE: + close_reason = "Abnormal closure"; + break; + case WSLAY_CODE_INVALID_FRAME_PAYLOAD_DATA: + close_reason = "Invalid frame payload data"; + break; + default: + close_reason = "Unknown"; + } + wslay_event_context_free(wsl_ctx); + wsl_ctx = nullptr; + close(-1); + return; + } } } } @@ -781,8 +864,10 @@ void WSLPeer::close(int p_code, String p_reason) { } } + heartbeat_waiting = false; in_buffer.clear(); packet_buffer.resize(0); + pending_message.clear(); } IPAddress WSLPeer::get_connected_host() const { diff --git a/modules/websocket/wsl_peer.h b/modules/websocket/wsl_peer.h index c4fe18630c..45cca48224 100644 --- a/modules/websocket/wsl_peer.h +++ b/modules/websocket/wsl_peer.h @@ -53,6 +53,10 @@ private: // Callbacks. static ssize_t _wsl_recv_callback(wslay_event_context_ptr ctx, uint8_t *data, size_t len, int flags, void *user_data); + static void _wsl_recv_start_callback(wslay_event_context_ptr ctx, const struct wslay_event_on_frame_recv_start_arg *arg, void *user_data); + static void _wsl_frame_recv_chunk_callback(wslay_event_context_ptr ctx, const struct wslay_event_on_frame_recv_chunk_arg *arg, void *user_data); + static void _wsl_frame_recv_end_callback(wslay_event_context_ptr ctx, void *user_data); + static ssize_t _wsl_send_callback(wslay_event_context_ptr ctx, const uint8_t *data, size_t len, int flags, void *user_data); static int _wsl_genmask_callback(wslay_event_context_ptr ctx, uint8_t *buf, size_t len, void *user_data); static void _wsl_msg_recv_callback(wslay_event_context_ptr ctx, const struct wslay_event_on_msg_recv_arg *arg, void *user_data); @@ -80,6 +84,16 @@ private: Resolver() {} }; + struct PendingMessage { + size_t payload_size = 0; + uint8_t opcode = 0; + + void clear() { + payload_size = 0; + opcode = 0; + } + }; + Resolver resolver; // WebSocket connection state. @@ -99,6 +113,9 @@ private: int close_code = -1; String close_reason; uint8_t was_string = 0; + uint64_t last_heartbeat = 0; + bool heartbeat_waiting = false; + PendingMessage pending_message; // WebSocket configuration. bool use_tls = true; diff --git a/platform/android/doc_classes/EditorExportPlatformAndroid.xml b/platform/android/doc_classes/EditorExportPlatformAndroid.xml index 8c8bca2b7c..983683fd78 100644 --- a/platform/android/doc_classes/EditorExportPlatformAndroid.xml +++ b/platform/android/doc_classes/EditorExportPlatformAndroid.xml @@ -151,6 +151,9 @@ <member name="permissions/access_location_extra_commands" type="bool" setter="" getter=""> Allows access to the extra location provider commands. See [url=https://developer.android.com/reference/android/Manifest.permission#ACCESS_LOCATION_EXTRA_COMMANDS]ACCESS_LOCATION_EXTRA_COMMANDS[/url]. </member> + <member name="permissions/access_media_location" type="bool" setter="" getter=""> + Allows an application to access any geographic locations persisted in the user's shared collection. See [url=https://developer.android.com/reference/android/Manifest.permission#ACCESS_MEDIA_LOCATION]ACCESS_MEDIA_LOCATION[/url]. + </member> <member name="permissions/access_mock_location" type="bool" setter="" getter=""> Allows an application to create mock location providers for testing. </member> @@ -412,6 +415,18 @@ <member name="permissions/read_logs" type="bool" setter="" getter=""> Allows an application to read the low-level system log files. See [url=https://developer.android.com/reference/android/Manifest.permission#READ_LOGS]READ_LOGS[/url]. </member> + <member name="permissions/read_media_audio" type="bool" setter="" getter=""> + Allows an application to read audio files from external storage. See [url=https://developer.android.com/reference/android/Manifest.permission#READ_MEDIA_AUDIO]READ_MEDIA_AUDIO[/url]. + </member> + <member name="permissions/read_media_images" type="bool" setter="" getter=""> + Allows an application to read image files from external storage. See [url=https://developer.android.com/reference/android/Manifest.permission#READ_MEDIA_IMAGES]READ_MEDIA_IMAGES[/url]. + </member> + <member name="permissions/read_media_video" type="bool" setter="" getter=""> + Allows an application to read video files from external storage. See [url=https://developer.android.com/reference/android/Manifest.permission#READ_MEDIA_VIDEO]READ_MEDIA_VIDEO[/url]. + </member> + <member name="permissions/read_media_visual_user_selected" type="bool" setter="" getter=""> + Allows an application to read image or video files from external storage that a user has selected via the permission prompt photo picker. See [url=https://developer.android.com/reference/android/Manifest.permission#READ_MEDIA_VISUAL_USER_SELECTED]READ_MEDIA_VISUAL_USER_SELECTED[/url]. + </member> <member name="permissions/read_phone_state" type="bool" setter="" getter=""> Allows read only access to phone state. See [url=https://developer.android.com/reference/android/Manifest.permission#READ_PHONE_STATE]READ_PHONE_STATE[/url]. </member> diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index aea09583b7..df3142ecbb 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -68,6 +68,7 @@ static const char *android_perms[] = { "ACCESS_COARSE_LOCATION", "ACCESS_FINE_LOCATION", "ACCESS_LOCATION_EXTRA_COMMANDS", + "ACCESS_MEDIA_LOCATION", "ACCESS_MOCK_LOCATION", "ACCESS_NETWORK_STATE", "ACCESS_SURFACE_FLINGER", @@ -155,6 +156,10 @@ static const char *android_perms[] = { "READ_HISTORY_BOOKMARKS", "READ_INPUT_STATE", "READ_LOGS", + "READ_MEDIA_AUDIO", + "READ_MEDIA_IMAGES", + "READ_MEDIA_VIDEO", + "READ_MEDIA_VISUAL_USER_SELECTED", "READ_PHONE_STATE", "READ_PROFILE", "READ_SMS", @@ -783,7 +788,7 @@ Error EditorExportPlatformAndroid::save_apk_so(void *p_userdata, const SharedObj return OK; } -Error EditorExportPlatformAndroid::save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { +Error EditorExportPlatformAndroid::save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed) { APKExportData *ed = static_cast<APKExportData *>(p_userdata); String dst_path = p_path.replace_first("res://", "assets/"); @@ -791,7 +796,7 @@ Error EditorExportPlatformAndroid::save_apk_file(void *p_userdata, const String return OK; } -Error EditorExportPlatformAndroid::ignore_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { +Error EditorExportPlatformAndroid::ignore_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed) { return OK; } @@ -1898,7 +1903,7 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "ext.domain.name"), "com.example.$genname", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name [default if blank]"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/signed"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "package/app_category", PROPERTY_HINT_ENUM, "Accessibility,Audio,Game,Image,Maps,News,Productivity,Social,Video"), APP_CATEGORY_GAME)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "package/app_category", PROPERTY_HINT_ENUM, "Accessibility,Audio,Game,Image,Maps,News,Productivity,Social,Video,Undefined"), APP_CATEGORY_GAME)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/retain_data_on_uninstall"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/exclude_from_recents"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/show_in_android_tv"), false)); @@ -3165,9 +3170,9 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP user_data.libs_directory = gradle_build_directory.path_join("libs"); user_data.debug = p_debug; if (p_flags.has_flag(DEBUG_FLAG_DUMB_CLIENT)) { - err = export_project_files(p_preset, p_debug, ignore_apk_file, &user_data, copy_gradle_so); + err = export_project_files(p_preset, p_debug, ignore_apk_file, nullptr, &user_data, copy_gradle_so); } else { - err = export_project_files(p_preset, p_debug, rename_and_store_file_in_gradle_project, &user_data, copy_gradle_so); + err = export_project_files(p_preset, p_debug, rename_and_store_file_in_gradle_project, nullptr, &user_data, copy_gradle_so); } if (err != OK) { add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Could not export project files to gradle project.")); @@ -3558,7 +3563,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP APKExportData ed; ed.ep = &ep; ed.apk = unaligned_apk; - err = export_project_files(p_preset, p_debug, ignore_apk_file, &ed, save_apk_so); + err = export_project_files(p_preset, p_debug, ignore_apk_file, nullptr, &ed, save_apk_so); } else { if (apk_expansion) { err = save_apk_expansion_file(p_preset, p_debug, p_path); @@ -3570,7 +3575,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP APKExportData ed; ed.ep = &ep; ed.apk = unaligned_apk; - err = export_project_files(p_preset, p_debug, save_apk_file, &ed, save_apk_so); + err = export_project_files(p_preset, p_debug, save_apk_file, nullptr, &ed, save_apk_so); } } diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h index 15e80f824d..23b6f9b193 100644 --- a/platform/android/export/export_plugin.h +++ b/platform/android/export/export_plugin.h @@ -142,9 +142,9 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { static Error save_apk_so(void *p_userdata, const SharedObject &p_so); - static Error save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); + static Error save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed); - static Error ignore_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); + static Error ignore_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed); static Error copy_gradle_so(void *p_userdata, const SharedObject &p_so); @@ -186,7 +186,7 @@ protected: void _notification(int p_what); public: - typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); + typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed); virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override; diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp index 9eddef6a4c..3603565805 100644 --- a/platform/android/export/gradle_export_util.cpp +++ b/platform/android/export/gradle_export_util.cpp @@ -88,6 +88,8 @@ int _get_app_category_value(int category_index) { return 7; case APP_CATEGORY_SOCIAL: return 4; + case APP_CATEGORY_UNDEFINED: + return -1; case APP_CATEGORY_VIDEO: return 2; case APP_CATEGORY_GAME: @@ -167,7 +169,7 @@ Error store_string_at_path(const String &p_path, const String &p_data) { // It is used by the export_project_files method to save all the asset files into the gradle project. // It's functionality mirrors that of the method save_apk_file. // This method will be called ONLY when gradle build is enabled. -Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) { +Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed) { CustomExportData *export_data = static_cast<CustomExportData *>(p_userdata); String dst_path = p_path.replace_first("res://", export_data->assets_directory + "/"); print_verbose("Saving project files from " + p_path + " into " + dst_path); @@ -311,17 +313,21 @@ String _get_application_tag(const Ref<EditorExportPlatform> &p_export_platform, " <application android:label=\"@string/godot_project_name_string\"\n" " android:allowBackup=\"%s\"\n" " android:icon=\"@mipmap/icon\"\n" - " android:appCategory=\"%s\"\n" " android:isGame=\"%s\"\n" " android:hasFragileUserData=\"%s\"\n" - " android:requestLegacyExternalStorage=\"%s\"\n" - " tools:replace=\"android:allowBackup,android:appCategory,android:isGame,android:hasFragileUserData,android:requestLegacyExternalStorage\"\n" - " tools:ignore=\"GoogleAppIndexingWarning\">\n\n", + " android:requestLegacyExternalStorage=\"%s\"\n", bool_to_string(p_preset->get("user_data_backup/allow")), - _get_app_category_label(app_category_index), bool_to_string(is_game), bool_to_string(p_preset->get("package/retain_data_on_uninstall")), bool_to_string(p_has_read_write_storage_permission)); + if (app_category_index != APP_CATEGORY_UNDEFINED) { + manifest_application_text += vformat(" android:appCategory=\"%s\"\n", _get_app_category_label(app_category_index)); + manifest_application_text += " tools:replace=\"android:allowBackup,android:appCategory,android:isGame,android:hasFragileUserData,android:requestLegacyExternalStorage\"\n"; + } else { + manifest_application_text += " tools:remove=\"android:appCategory\"\n"; + manifest_application_text += " tools:replace=\"android:allowBackup,android:isGame,android:hasFragileUserData,android:requestLegacyExternalStorage\"\n"; + } + manifest_application_text += " tools:ignore=\"GoogleAppIndexingWarning\">\n\n"; Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins(); for (int i = 0; i < export_plugins.size(); i++) { diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h index 9f8e476f73..a528fd5211 100644 --- a/platform/android/export/gradle_export_util.h +++ b/platform/android/export/gradle_export_util.h @@ -55,6 +55,7 @@ static const int APP_CATEGORY_NEWS = 5; static const int APP_CATEGORY_PRODUCTIVITY = 6; static const int APP_CATEGORY_SOCIAL = 7; static const int APP_CATEGORY_VIDEO = 8; +static const int APP_CATEGORY_UNDEFINED = 9; // Supported XR modes. // This should match the entries in 'platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java' @@ -92,7 +93,7 @@ Error store_string_at_path(const String &p_path, const String &p_data); // It is used by the export_project_files method to save all the asset files into the gradle project. // It's functionality mirrors that of the method save_apk_file. // This method will be called ONLY when gradle build is enabled. -Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); +Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key, uint64_t p_seed); // Creates strings.xml files inside the gradle project for different locales. Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset, const String &project_name, const String &p_gradle_build_dir); diff --git a/platform/android/java/app/res/values/themes.xml b/platform/android/java/app/res/values/themes.xml index 3ab8401928..3c86e54df5 100644 --- a/platform/android/java/app/res/values/themes.xml +++ b/platform/android/java/app/res/values/themes.xml @@ -1,7 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <style name="GodotAppMainTheme" parent="@android:style/Theme.Black.NoTitleBar"/> + <style name="GodotAppMainTheme" parent="@android:style/Theme.DeviceDefault.NoActionBar"> + <item name ="android:windowDrawsSystemBarBackgrounds">false</item> + </style> <style name="GodotAppSplashTheme" parent="Theme.SplashScreen"> <!-- Set the splash screen background, animated icon, and animation diff --git a/platform/android/java/editor/build.gradle b/platform/android/java/editor/build.gradle index 45222ca3b0..276d74b75b 100644 --- a/platform/android/java/editor/build.gradle +++ b/platform/android/java/editor/build.gradle @@ -173,7 +173,7 @@ dependencies { implementation "androidx.window:window:1.3.0" implementation "androidx.core:core-splashscreen:$versions.splashscreenVersion" implementation "androidx.constraintlayout:constraintlayout:2.1.4" - implementation "org.bouncycastle:bcprov-jdk15to18:1.77" + implementation "org.bouncycastle:bcprov-jdk15to18:1.78" // Meta dependencies horizonosImplementation "org.godotengine:godot-openxr-vendors-meta:3.0.0-stable" diff --git a/platform/android/java/editor/src/main/res/values/themes.xml b/platform/android/java/editor/src/main/res/values/themes.xml index 2b352247db..8de2c6e288 100644 --- a/platform/android/java/editor/src/main/res/values/themes.xml +++ b/platform/android/java/editor/src/main/res/values/themes.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <style name="GodotEditorTheme" parent="@android:style/Theme.Black.NoTitleBar.Fullscreen"> + <style name="GodotEditorTheme" parent="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen"> + <item name ="android:windowDrawsSystemBarBackgrounds">false</item> </style> <style name="GodotEditorSplashScreenTheme" parent="Theme.SplashScreen.IconBackground"> diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle index f6aee434e5..f273105efc 100644 --- a/platform/android/java/lib/build.gradle +++ b/platform/android/java/lib/build.gradle @@ -106,8 +106,8 @@ android { boolean devBuild = buildType == "dev" boolean debugSymbols = devBuild boolean runTests = devBuild - boolean productionBuild = !devBuild boolean storeRelease = buildType == "release" + boolean productionBuild = storeRelease def sconsTarget = flavorName if (sconsTarget == "template") { diff --git a/platform/android/net_socket_android.cpp b/platform/android/net_socket_android.cpp index 8f0ee51fac..9ab7d6a04f 100644 --- a/platform/android/net_socket_android.cpp +++ b/platform/android/net_socket_android.cpp @@ -84,7 +84,7 @@ NetSocketAndroid::~NetSocketAndroid() { } void NetSocketAndroid::close() { - NetSocketPosix::close(); + NetSocketUnix::close(); if (wants_broadcast) { multicast_lock_release(); } @@ -96,7 +96,7 @@ void NetSocketAndroid::close() { } Error NetSocketAndroid::set_broadcasting_enabled(bool p_enabled) { - Error err = NetSocketPosix::set_broadcasting_enabled(p_enabled); + Error err = NetSocketUnix::set_broadcasting_enabled(p_enabled); if (err != OK) { return err; } @@ -115,7 +115,7 @@ Error NetSocketAndroid::set_broadcasting_enabled(bool p_enabled) { } Error NetSocketAndroid::join_multicast_group(const IPAddress &p_multi_address, const String &p_if_name) { - Error err = NetSocketPosix::join_multicast_group(p_multi_address, p_if_name); + Error err = NetSocketUnix::join_multicast_group(p_multi_address, p_if_name); if (err != OK) { return err; } @@ -129,7 +129,7 @@ Error NetSocketAndroid::join_multicast_group(const IPAddress &p_multi_address, c } Error NetSocketAndroid::leave_multicast_group(const IPAddress &p_multi_address, const String &p_if_name) { - Error err = NetSocketPosix::leave_multicast_group(p_multi_address, p_if_name); + Error err = NetSocketUnix::leave_multicast_group(p_multi_address, p_if_name); if (err != OK) { return err; } diff --git a/platform/android/net_socket_android.h b/platform/android/net_socket_android.h index 26cb2d4e3d..c33146d2d8 100644 --- a/platform/android/net_socket_android.h +++ b/platform/android/net_socket_android.h @@ -31,7 +31,7 @@ #ifndef NET_SOCKET_ANDROID_H #define NET_SOCKET_ANDROID_H -#include "drivers/unix/net_socket_posix.h" +#include "drivers/unix/net_socket_unix.h" #include <jni.h> @@ -44,7 +44,7 @@ * the lock when broadcasting is enabled/disabled on a socket, or that socket * joins/leaves a multicast group. */ -class NetSocketAndroid : public NetSocketPosix { +class NetSocketAndroid : public NetSocketUnix { private: static jobject net_utils; static jclass cls; diff --git a/platform/ios/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp index d6cd2e0f3c..3c5a930bab 100644 --- a/platform/ios/export/export_plugin.cpp +++ b/platform/ios/export/export_plugin.cpp @@ -1082,7 +1082,7 @@ Error EditorExportPlatformIOS::_export_loading_screen_file(const Ref<EditorExpor } if (splash.is_null()) { - splash = Ref<Image>(memnew(Image(boot_splash_png))); + splash.instantiate(boot_splash_png); } // Using same image for both @2x and @3x diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index 2fd573da75..c8202b147d 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -279,16 +279,18 @@ def configure(env: "SConsEnvironment"): env.ParseConfig("pkg-config libwebp --cflags --libs") if not env["builtin_mbedtls"]: - # mbedTLS does not provide a pkgconfig config yet. See https://github.com/ARMmbed/mbedtls/issues/228 - env.Append(LIBS=["mbedtls", "mbedcrypto", "mbedx509"]) + # mbedTLS only provides a pkgconfig file since 3.6.0, but we still support 2.28.x, + # so fallback to manually specifying LIBS if it fails. + if os.system("pkg-config --exists mbedtls") == 0: # 0 means found + env.ParseConfig("pkg-config mbedtls mbedcrypto mbedx509 --cflags --libs") + else: + env.Append(LIBS=["mbedtls", "mbedcrypto", "mbedx509"]) if not env["builtin_wslay"]: env.ParseConfig("pkg-config libwslay --cflags --libs") if not env["builtin_miniupnpc"]: - # No pkgconfig file so far, hardcode default paths. - env.Prepend(CPPPATH=["/usr/include/miniupnpc"]) - env.Append(LIBS=["miniupnpc"]) + env.ParseConfig("pkg-config miniupnpc --cflags --libs") # On Linux wchar_t should be 32-bits # 16-bit library shouldn't be required due to compiler optimizations diff --git a/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c index bba21b9cb7..7e1f3b8072 100644 --- a/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c +++ b/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c @@ -1,12 +1,8 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by generate-wrapper.py 0.3 on 2023-01-23 15:09:53 -// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h --sys-include "thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h" --soname libXcursor.so.1 --init-name xcursor --output-header ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c +// generated by generate-wrapper.py 0.6 on 2024-11-09 02:52:36 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h --sys-include thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h --soname libXcursor.so.1 --init-name xcursor --output-header ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c --ignore-other // -// NOTE: Generated from Xcursor 1.2.0. -// This has been handpatched to workaround some issues with the generator that -// will be eventually fixed. In this case, non-existent symbols inherited from -// libX11, but absent in libXcursor.so.1, were removed. #include <stdint.h> #define XcursorImageCreate XcursorImageCreate_dylibloader_orig_xcursor @@ -130,65 +126,65 @@ #undef XcursorSetThemeCore #include <dlfcn.h> #include <stdio.h> -XcursorImage* (*XcursorImageCreate_dylibloader_wrapper_xcursor)( int, int); -void (*XcursorImageDestroy_dylibloader_wrapper_xcursor)( XcursorImage*); -XcursorImages* (*XcursorImagesCreate_dylibloader_wrapper_xcursor)( int); -void (*XcursorImagesDestroy_dylibloader_wrapper_xcursor)( XcursorImages*); -void (*XcursorImagesSetName_dylibloader_wrapper_xcursor)( XcursorImages*,const char*); -XcursorCursors* (*XcursorCursorsCreate_dylibloader_wrapper_xcursor)( Display*, int); -void (*XcursorCursorsDestroy_dylibloader_wrapper_xcursor)( XcursorCursors*); -XcursorAnimate* (*XcursorAnimateCreate_dylibloader_wrapper_xcursor)( XcursorCursors*); -void (*XcursorAnimateDestroy_dylibloader_wrapper_xcursor)( XcursorAnimate*); -Cursor (*XcursorAnimateNext_dylibloader_wrapper_xcursor)( XcursorAnimate*); -XcursorComment* (*XcursorCommentCreate_dylibloader_wrapper_xcursor)( XcursorUInt, int); -void (*XcursorCommentDestroy_dylibloader_wrapper_xcursor)( XcursorComment*); -XcursorComments* (*XcursorCommentsCreate_dylibloader_wrapper_xcursor)( int); -void (*XcursorCommentsDestroy_dylibloader_wrapper_xcursor)( XcursorComments*); -XcursorImage* (*XcursorXcFileLoadImage_dylibloader_wrapper_xcursor)( XcursorFile*, int); -XcursorImages* (*XcursorXcFileLoadImages_dylibloader_wrapper_xcursor)( XcursorFile*, int); -XcursorImages* (*XcursorXcFileLoadAllImages_dylibloader_wrapper_xcursor)( XcursorFile*); -XcursorBool (*XcursorXcFileLoad_dylibloader_wrapper_xcursor)( XcursorFile*, XcursorComments**, XcursorImages**); -XcursorBool (*XcursorXcFileSave_dylibloader_wrapper_xcursor)( XcursorFile*,const XcursorComments*,const XcursorImages*); -XcursorImage* (*XcursorFileLoadImage_dylibloader_wrapper_xcursor)( FILE*, int); -XcursorImages* (*XcursorFileLoadImages_dylibloader_wrapper_xcursor)( FILE*, int); -XcursorImages* (*XcursorFileLoadAllImages_dylibloader_wrapper_xcursor)( FILE*); -XcursorBool (*XcursorFileLoad_dylibloader_wrapper_xcursor)( FILE*, XcursorComments**, XcursorImages**); -XcursorBool (*XcursorFileSaveImages_dylibloader_wrapper_xcursor)( FILE*,const XcursorImages*); -XcursorBool (*XcursorFileSave_dylibloader_wrapper_xcursor)( FILE*,const XcursorComments*,const XcursorImages*); -XcursorImage* (*XcursorFilenameLoadImage_dylibloader_wrapper_xcursor)(const char*, int); -XcursorImages* (*XcursorFilenameLoadImages_dylibloader_wrapper_xcursor)(const char*, int); -XcursorImages* (*XcursorFilenameLoadAllImages_dylibloader_wrapper_xcursor)(const char*); -XcursorBool (*XcursorFilenameLoad_dylibloader_wrapper_xcursor)(const char*, XcursorComments**, XcursorImages**); -XcursorBool (*XcursorFilenameSaveImages_dylibloader_wrapper_xcursor)(const char*,const XcursorImages*); -XcursorBool (*XcursorFilenameSave_dylibloader_wrapper_xcursor)(const char*,const XcursorComments*,const XcursorImages*); -XcursorImage* (*XcursorLibraryLoadImage_dylibloader_wrapper_xcursor)(const char*,const char*, int); -XcursorImages* (*XcursorLibraryLoadImages_dylibloader_wrapper_xcursor)(const char*,const char*, int); -const char* (*XcursorLibraryPath_dylibloader_wrapper_xcursor)( void); -int (*XcursorLibraryShape_dylibloader_wrapper_xcursor)(const char*); -Cursor (*XcursorImageLoadCursor_dylibloader_wrapper_xcursor)( Display*,const XcursorImage*); -XcursorCursors* (*XcursorImagesLoadCursors_dylibloader_wrapper_xcursor)( Display*,const XcursorImages*); -Cursor (*XcursorImagesLoadCursor_dylibloader_wrapper_xcursor)( Display*,const XcursorImages*); -Cursor (*XcursorFilenameLoadCursor_dylibloader_wrapper_xcursor)( Display*,const char*); -XcursorCursors* (*XcursorFilenameLoadCursors_dylibloader_wrapper_xcursor)( Display*,const char*); -Cursor (*XcursorLibraryLoadCursor_dylibloader_wrapper_xcursor)( Display*,const char*); -XcursorCursors* (*XcursorLibraryLoadCursors_dylibloader_wrapper_xcursor)( Display*,const char*); -XcursorImage* (*XcursorShapeLoadImage_dylibloader_wrapper_xcursor)( unsigned int,const char*, int); -XcursorImages* (*XcursorShapeLoadImages_dylibloader_wrapper_xcursor)( unsigned int,const char*, int); -Cursor (*XcursorShapeLoadCursor_dylibloader_wrapper_xcursor)( Display*, unsigned int); -XcursorCursors* (*XcursorShapeLoadCursors_dylibloader_wrapper_xcursor)( Display*, unsigned int); -Cursor (*XcursorTryShapeCursor_dylibloader_wrapper_xcursor)( Display*, Font, Font, unsigned int, unsigned int,const XColor*,const XColor*); -void (*XcursorNoticeCreateBitmap_dylibloader_wrapper_xcursor)( Display*, Pixmap, unsigned int, unsigned int); -void (*XcursorNoticePutBitmap_dylibloader_wrapper_xcursor)( Display*, Drawable, XImage*); -Cursor (*XcursorTryShapeBitmapCursor_dylibloader_wrapper_xcursor)( Display*, Pixmap, Pixmap, XColor*, XColor*, unsigned int, unsigned int); -void (*XcursorImageHash_dylibloader_wrapper_xcursor)( XImage*, unsigned char [16]); -XcursorBool (*XcursorSupportsARGB_dylibloader_wrapper_xcursor)( Display*); -XcursorBool (*XcursorSupportsAnim_dylibloader_wrapper_xcursor)( Display*); -XcursorBool (*XcursorSetDefaultSize_dylibloader_wrapper_xcursor)( Display*, int); -int (*XcursorGetDefaultSize_dylibloader_wrapper_xcursor)( Display*); -XcursorBool (*XcursorSetTheme_dylibloader_wrapper_xcursor)( Display*,const char*); -char* (*XcursorGetTheme_dylibloader_wrapper_xcursor)( Display*); -XcursorBool (*XcursorGetThemeCore_dylibloader_wrapper_xcursor)( Display*); -XcursorBool (*XcursorSetThemeCore_dylibloader_wrapper_xcursor)( Display*, XcursorBool); +XcursorImage *(*XcursorImageCreate_dylibloader_wrapper_xcursor)(int, int); +void (*XcursorImageDestroy_dylibloader_wrapper_xcursor)(XcursorImage *); +XcursorImages *(*XcursorImagesCreate_dylibloader_wrapper_xcursor)(int); +void (*XcursorImagesDestroy_dylibloader_wrapper_xcursor)(XcursorImages *); +void (*XcursorImagesSetName_dylibloader_wrapper_xcursor)(XcursorImages *, const char *); +XcursorCursors *(*XcursorCursorsCreate_dylibloader_wrapper_xcursor)(Display *, int); +void (*XcursorCursorsDestroy_dylibloader_wrapper_xcursor)(XcursorCursors *); +XcursorAnimate *(*XcursorAnimateCreate_dylibloader_wrapper_xcursor)(XcursorCursors *); +void (*XcursorAnimateDestroy_dylibloader_wrapper_xcursor)(XcursorAnimate *); +Cursor (*XcursorAnimateNext_dylibloader_wrapper_xcursor)(XcursorAnimate *); +XcursorComment *(*XcursorCommentCreate_dylibloader_wrapper_xcursor)(XcursorUInt, int); +void (*XcursorCommentDestroy_dylibloader_wrapper_xcursor)(XcursorComment *); +XcursorComments *(*XcursorCommentsCreate_dylibloader_wrapper_xcursor)(int); +void (*XcursorCommentsDestroy_dylibloader_wrapper_xcursor)(XcursorComments *); +XcursorImage *(*XcursorXcFileLoadImage_dylibloader_wrapper_xcursor)(XcursorFile *, int); +XcursorImages *(*XcursorXcFileLoadImages_dylibloader_wrapper_xcursor)(XcursorFile *, int); +XcursorImages *(*XcursorXcFileLoadAllImages_dylibloader_wrapper_xcursor)(XcursorFile *); +XcursorBool (*XcursorXcFileLoad_dylibloader_wrapper_xcursor)(XcursorFile *, XcursorComments **, XcursorImages **); +XcursorBool (*XcursorXcFileSave_dylibloader_wrapper_xcursor)(XcursorFile *, const XcursorComments *, const XcursorImages *); +XcursorImage *(*XcursorFileLoadImage_dylibloader_wrapper_xcursor)(FILE *, int); +XcursorImages *(*XcursorFileLoadImages_dylibloader_wrapper_xcursor)(FILE *, int); +XcursorImages *(*XcursorFileLoadAllImages_dylibloader_wrapper_xcursor)(FILE *); +XcursorBool (*XcursorFileLoad_dylibloader_wrapper_xcursor)(FILE *, XcursorComments **, XcursorImages **); +XcursorBool (*XcursorFileSaveImages_dylibloader_wrapper_xcursor)(FILE *, const XcursorImages *); +XcursorBool (*XcursorFileSave_dylibloader_wrapper_xcursor)(FILE *, const XcursorComments *, const XcursorImages *); +XcursorImage *(*XcursorFilenameLoadImage_dylibloader_wrapper_xcursor)(const char *, int); +XcursorImages *(*XcursorFilenameLoadImages_dylibloader_wrapper_xcursor)(const char *, int); +XcursorImages *(*XcursorFilenameLoadAllImages_dylibloader_wrapper_xcursor)(const char *); +XcursorBool (*XcursorFilenameLoad_dylibloader_wrapper_xcursor)(const char *, XcursorComments **, XcursorImages **); +XcursorBool (*XcursorFilenameSaveImages_dylibloader_wrapper_xcursor)(const char *, const XcursorImages *); +XcursorBool (*XcursorFilenameSave_dylibloader_wrapper_xcursor)(const char *, const XcursorComments *, const XcursorImages *); +XcursorImage *(*XcursorLibraryLoadImage_dylibloader_wrapper_xcursor)(const char *, const char *, int); +XcursorImages *(*XcursorLibraryLoadImages_dylibloader_wrapper_xcursor)(const char *, const char *, int); +const char *(*XcursorLibraryPath_dylibloader_wrapper_xcursor)(void); +int (*XcursorLibraryShape_dylibloader_wrapper_xcursor)(const char *); +Cursor (*XcursorImageLoadCursor_dylibloader_wrapper_xcursor)(Display *, const XcursorImage *); +XcursorCursors *(*XcursorImagesLoadCursors_dylibloader_wrapper_xcursor)(Display *, const XcursorImages *); +Cursor (*XcursorImagesLoadCursor_dylibloader_wrapper_xcursor)(Display *, const XcursorImages *); +Cursor (*XcursorFilenameLoadCursor_dylibloader_wrapper_xcursor)(Display *, const char *); +XcursorCursors *(*XcursorFilenameLoadCursors_dylibloader_wrapper_xcursor)(Display *, const char *); +Cursor (*XcursorLibraryLoadCursor_dylibloader_wrapper_xcursor)(Display *, const char *); +XcursorCursors *(*XcursorLibraryLoadCursors_dylibloader_wrapper_xcursor)(Display *, const char *); +XcursorImage *(*XcursorShapeLoadImage_dylibloader_wrapper_xcursor)(unsigned int, const char *, int); +XcursorImages *(*XcursorShapeLoadImages_dylibloader_wrapper_xcursor)(unsigned int, const char *, int); +Cursor (*XcursorShapeLoadCursor_dylibloader_wrapper_xcursor)(Display *, unsigned int); +XcursorCursors *(*XcursorShapeLoadCursors_dylibloader_wrapper_xcursor)(Display *, unsigned int); +Cursor (*XcursorTryShapeCursor_dylibloader_wrapper_xcursor)(Display *, Font, Font, unsigned int, unsigned int, const XColor *, const XColor *); +void (*XcursorNoticeCreateBitmap_dylibloader_wrapper_xcursor)(Display *, Pixmap, unsigned int, unsigned int); +void (*XcursorNoticePutBitmap_dylibloader_wrapper_xcursor)(Display *, Drawable, XImage *); +Cursor (*XcursorTryShapeBitmapCursor_dylibloader_wrapper_xcursor)(Display *, Pixmap, Pixmap, XColor *, XColor *, unsigned int, unsigned int); +void (*XcursorImageHash_dylibloader_wrapper_xcursor)(XImage *, unsigned char [16]); +XcursorBool (*XcursorSupportsARGB_dylibloader_wrapper_xcursor)(Display *); +XcursorBool (*XcursorSupportsAnim_dylibloader_wrapper_xcursor)(Display *); +XcursorBool (*XcursorSetDefaultSize_dylibloader_wrapper_xcursor)(Display *, int); +int (*XcursorGetDefaultSize_dylibloader_wrapper_xcursor)(Display *); +XcursorBool (*XcursorSetTheme_dylibloader_wrapper_xcursor)(Display *, const char *); +char *(*XcursorGetTheme_dylibloader_wrapper_xcursor)(Display *); +XcursorBool (*XcursorGetThemeCore_dylibloader_wrapper_xcursor)(Display *); +XcursorBool (*XcursorSetThemeCore_dylibloader_wrapper_xcursor)(Display *, XcursorBool); int initialize_xcursor(int verbose) { void *handle; char *error; diff --git a/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h index 9f8d8bbca2..7266cfe609 100644 --- a/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h +++ b/platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h @@ -2,13 +2,9 @@ #define DYLIBLOAD_WRAPPER_XCURSOR // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by generate-wrapper.py 0.3 on 2023-01-23 15:09:53 -// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h --sys-include "thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h" --soname libXcursor.so.1 --init-name xcursor --output-header ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c +// generated by generate-wrapper.py 0.6 on 2024-11-09 02:52:36 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h --sys-include thirdparty/linuxbsd_headers/X11/Xcursor/Xcursor.h --soname libXcursor.so.1 --init-name xcursor --output-header ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xcursor-so_wrap.c --ignore-other // -// NOTE: Generated from Xcursor 1.2.0. -// This has been handpatched to workaround some issues with the generator that -// will be eventually fixed. In this case, non-existent symbols inherited from -// libX11, but absent in libXcursor.so.1, were removed. #include <stdint.h> #define XcursorImageCreate XcursorImageCreate_dylibloader_orig_xcursor @@ -192,65 +188,65 @@ extern "C" { #define XcursorGetTheme XcursorGetTheme_dylibloader_wrapper_xcursor #define XcursorGetThemeCore XcursorGetThemeCore_dylibloader_wrapper_xcursor #define XcursorSetThemeCore XcursorSetThemeCore_dylibloader_wrapper_xcursor -extern XcursorImage* (*XcursorImageCreate_dylibloader_wrapper_xcursor)( int, int); -extern void (*XcursorImageDestroy_dylibloader_wrapper_xcursor)( XcursorImage*); -extern XcursorImages* (*XcursorImagesCreate_dylibloader_wrapper_xcursor)( int); -extern void (*XcursorImagesDestroy_dylibloader_wrapper_xcursor)( XcursorImages*); -extern void (*XcursorImagesSetName_dylibloader_wrapper_xcursor)( XcursorImages*,const char*); -extern XcursorCursors* (*XcursorCursorsCreate_dylibloader_wrapper_xcursor)( Display*, int); -extern void (*XcursorCursorsDestroy_dylibloader_wrapper_xcursor)( XcursorCursors*); -extern XcursorAnimate* (*XcursorAnimateCreate_dylibloader_wrapper_xcursor)( XcursorCursors*); -extern void (*XcursorAnimateDestroy_dylibloader_wrapper_xcursor)( XcursorAnimate*); -extern Cursor (*XcursorAnimateNext_dylibloader_wrapper_xcursor)( XcursorAnimate*); -extern XcursorComment* (*XcursorCommentCreate_dylibloader_wrapper_xcursor)( XcursorUInt, int); -extern void (*XcursorCommentDestroy_dylibloader_wrapper_xcursor)( XcursorComment*); -extern XcursorComments* (*XcursorCommentsCreate_dylibloader_wrapper_xcursor)( int); -extern void (*XcursorCommentsDestroy_dylibloader_wrapper_xcursor)( XcursorComments*); -extern XcursorImage* (*XcursorXcFileLoadImage_dylibloader_wrapper_xcursor)( XcursorFile*, int); -extern XcursorImages* (*XcursorXcFileLoadImages_dylibloader_wrapper_xcursor)( XcursorFile*, int); -extern XcursorImages* (*XcursorXcFileLoadAllImages_dylibloader_wrapper_xcursor)( XcursorFile*); -extern XcursorBool (*XcursorXcFileLoad_dylibloader_wrapper_xcursor)( XcursorFile*, XcursorComments**, XcursorImages**); -extern XcursorBool (*XcursorXcFileSave_dylibloader_wrapper_xcursor)( XcursorFile*,const XcursorComments*,const XcursorImages*); -extern XcursorImage* (*XcursorFileLoadImage_dylibloader_wrapper_xcursor)( FILE*, int); -extern XcursorImages* (*XcursorFileLoadImages_dylibloader_wrapper_xcursor)( FILE*, int); -extern XcursorImages* (*XcursorFileLoadAllImages_dylibloader_wrapper_xcursor)( FILE*); -extern XcursorBool (*XcursorFileLoad_dylibloader_wrapper_xcursor)( FILE*, XcursorComments**, XcursorImages**); -extern XcursorBool (*XcursorFileSaveImages_dylibloader_wrapper_xcursor)( FILE*,const XcursorImages*); -extern XcursorBool (*XcursorFileSave_dylibloader_wrapper_xcursor)( FILE*,const XcursorComments*,const XcursorImages*); -extern XcursorImage* (*XcursorFilenameLoadImage_dylibloader_wrapper_xcursor)(const char*, int); -extern XcursorImages* (*XcursorFilenameLoadImages_dylibloader_wrapper_xcursor)(const char*, int); -extern XcursorImages* (*XcursorFilenameLoadAllImages_dylibloader_wrapper_xcursor)(const char*); -extern XcursorBool (*XcursorFilenameLoad_dylibloader_wrapper_xcursor)(const char*, XcursorComments**, XcursorImages**); -extern XcursorBool (*XcursorFilenameSaveImages_dylibloader_wrapper_xcursor)(const char*,const XcursorImages*); -extern XcursorBool (*XcursorFilenameSave_dylibloader_wrapper_xcursor)(const char*,const XcursorComments*,const XcursorImages*); -extern XcursorImage* (*XcursorLibraryLoadImage_dylibloader_wrapper_xcursor)(const char*,const char*, int); -extern XcursorImages* (*XcursorLibraryLoadImages_dylibloader_wrapper_xcursor)(const char*,const char*, int); -extern const char* (*XcursorLibraryPath_dylibloader_wrapper_xcursor)( void); -extern int (*XcursorLibraryShape_dylibloader_wrapper_xcursor)(const char*); -extern Cursor (*XcursorImageLoadCursor_dylibloader_wrapper_xcursor)( Display*,const XcursorImage*); -extern XcursorCursors* (*XcursorImagesLoadCursors_dylibloader_wrapper_xcursor)( Display*,const XcursorImages*); -extern Cursor (*XcursorImagesLoadCursor_dylibloader_wrapper_xcursor)( Display*,const XcursorImages*); -extern Cursor (*XcursorFilenameLoadCursor_dylibloader_wrapper_xcursor)( Display*,const char*); -extern XcursorCursors* (*XcursorFilenameLoadCursors_dylibloader_wrapper_xcursor)( Display*,const char*); -extern Cursor (*XcursorLibraryLoadCursor_dylibloader_wrapper_xcursor)( Display*,const char*); -extern XcursorCursors* (*XcursorLibraryLoadCursors_dylibloader_wrapper_xcursor)( Display*,const char*); -extern XcursorImage* (*XcursorShapeLoadImage_dylibloader_wrapper_xcursor)( unsigned int,const char*, int); -extern XcursorImages* (*XcursorShapeLoadImages_dylibloader_wrapper_xcursor)( unsigned int,const char*, int); -extern Cursor (*XcursorShapeLoadCursor_dylibloader_wrapper_xcursor)( Display*, unsigned int); -extern XcursorCursors* (*XcursorShapeLoadCursors_dylibloader_wrapper_xcursor)( Display*, unsigned int); -extern Cursor (*XcursorTryShapeCursor_dylibloader_wrapper_xcursor)( Display*, Font, Font, unsigned int, unsigned int,const XColor*,const XColor*); -extern void (*XcursorNoticeCreateBitmap_dylibloader_wrapper_xcursor)( Display*, Pixmap, unsigned int, unsigned int); -extern void (*XcursorNoticePutBitmap_dylibloader_wrapper_xcursor)( Display*, Drawable, XImage*); -extern Cursor (*XcursorTryShapeBitmapCursor_dylibloader_wrapper_xcursor)( Display*, Pixmap, Pixmap, XColor*, XColor*, unsigned int, unsigned int); -extern void (*XcursorImageHash_dylibloader_wrapper_xcursor)( XImage*, unsigned char [16]); -extern XcursorBool (*XcursorSupportsARGB_dylibloader_wrapper_xcursor)( Display*); -extern XcursorBool (*XcursorSupportsAnim_dylibloader_wrapper_xcursor)( Display*); -extern XcursorBool (*XcursorSetDefaultSize_dylibloader_wrapper_xcursor)( Display*, int); -extern int (*XcursorGetDefaultSize_dylibloader_wrapper_xcursor)( Display*); -extern XcursorBool (*XcursorSetTheme_dylibloader_wrapper_xcursor)( Display*,const char*); -extern char* (*XcursorGetTheme_dylibloader_wrapper_xcursor)( Display*); -extern XcursorBool (*XcursorGetThemeCore_dylibloader_wrapper_xcursor)( Display*); -extern XcursorBool (*XcursorSetThemeCore_dylibloader_wrapper_xcursor)( Display*, XcursorBool); +extern XcursorImage *(*XcursorImageCreate_dylibloader_wrapper_xcursor)(int, int); +extern void (*XcursorImageDestroy_dylibloader_wrapper_xcursor)(XcursorImage *); +extern XcursorImages *(*XcursorImagesCreate_dylibloader_wrapper_xcursor)(int); +extern void (*XcursorImagesDestroy_dylibloader_wrapper_xcursor)(XcursorImages *); +extern void (*XcursorImagesSetName_dylibloader_wrapper_xcursor)(XcursorImages *, const char *); +extern XcursorCursors *(*XcursorCursorsCreate_dylibloader_wrapper_xcursor)(Display *, int); +extern void (*XcursorCursorsDestroy_dylibloader_wrapper_xcursor)(XcursorCursors *); +extern XcursorAnimate *(*XcursorAnimateCreate_dylibloader_wrapper_xcursor)(XcursorCursors *); +extern void (*XcursorAnimateDestroy_dylibloader_wrapper_xcursor)(XcursorAnimate *); +extern Cursor (*XcursorAnimateNext_dylibloader_wrapper_xcursor)(XcursorAnimate *); +extern XcursorComment *(*XcursorCommentCreate_dylibloader_wrapper_xcursor)(XcursorUInt, int); +extern void (*XcursorCommentDestroy_dylibloader_wrapper_xcursor)(XcursorComment *); +extern XcursorComments *(*XcursorCommentsCreate_dylibloader_wrapper_xcursor)(int); +extern void (*XcursorCommentsDestroy_dylibloader_wrapper_xcursor)(XcursorComments *); +extern XcursorImage *(*XcursorXcFileLoadImage_dylibloader_wrapper_xcursor)(XcursorFile *, int); +extern XcursorImages *(*XcursorXcFileLoadImages_dylibloader_wrapper_xcursor)(XcursorFile *, int); +extern XcursorImages *(*XcursorXcFileLoadAllImages_dylibloader_wrapper_xcursor)(XcursorFile *); +extern XcursorBool (*XcursorXcFileLoad_dylibloader_wrapper_xcursor)(XcursorFile *, XcursorComments **, XcursorImages **); +extern XcursorBool (*XcursorXcFileSave_dylibloader_wrapper_xcursor)(XcursorFile *, const XcursorComments *, const XcursorImages *); +extern XcursorImage *(*XcursorFileLoadImage_dylibloader_wrapper_xcursor)(FILE *, int); +extern XcursorImages *(*XcursorFileLoadImages_dylibloader_wrapper_xcursor)(FILE *, int); +extern XcursorImages *(*XcursorFileLoadAllImages_dylibloader_wrapper_xcursor)(FILE *); +extern XcursorBool (*XcursorFileLoad_dylibloader_wrapper_xcursor)(FILE *, XcursorComments **, XcursorImages **); +extern XcursorBool (*XcursorFileSaveImages_dylibloader_wrapper_xcursor)(FILE *, const XcursorImages *); +extern XcursorBool (*XcursorFileSave_dylibloader_wrapper_xcursor)(FILE *, const XcursorComments *, const XcursorImages *); +extern XcursorImage *(*XcursorFilenameLoadImage_dylibloader_wrapper_xcursor)(const char *, int); +extern XcursorImages *(*XcursorFilenameLoadImages_dylibloader_wrapper_xcursor)(const char *, int); +extern XcursorImages *(*XcursorFilenameLoadAllImages_dylibloader_wrapper_xcursor)(const char *); +extern XcursorBool (*XcursorFilenameLoad_dylibloader_wrapper_xcursor)(const char *, XcursorComments **, XcursorImages **); +extern XcursorBool (*XcursorFilenameSaveImages_dylibloader_wrapper_xcursor)(const char *, const XcursorImages *); +extern XcursorBool (*XcursorFilenameSave_dylibloader_wrapper_xcursor)(const char *, const XcursorComments *, const XcursorImages *); +extern XcursorImage *(*XcursorLibraryLoadImage_dylibloader_wrapper_xcursor)(const char *, const char *, int); +extern XcursorImages *(*XcursorLibraryLoadImages_dylibloader_wrapper_xcursor)(const char *, const char *, int); +extern const char *(*XcursorLibraryPath_dylibloader_wrapper_xcursor)(void); +extern int (*XcursorLibraryShape_dylibloader_wrapper_xcursor)(const char *); +extern Cursor (*XcursorImageLoadCursor_dylibloader_wrapper_xcursor)(Display *, const XcursorImage *); +extern XcursorCursors *(*XcursorImagesLoadCursors_dylibloader_wrapper_xcursor)(Display *, const XcursorImages *); +extern Cursor (*XcursorImagesLoadCursor_dylibloader_wrapper_xcursor)(Display *, const XcursorImages *); +extern Cursor (*XcursorFilenameLoadCursor_dylibloader_wrapper_xcursor)(Display *, const char *); +extern XcursorCursors *(*XcursorFilenameLoadCursors_dylibloader_wrapper_xcursor)(Display *, const char *); +extern Cursor (*XcursorLibraryLoadCursor_dylibloader_wrapper_xcursor)(Display *, const char *); +extern XcursorCursors *(*XcursorLibraryLoadCursors_dylibloader_wrapper_xcursor)(Display *, const char *); +extern XcursorImage *(*XcursorShapeLoadImage_dylibloader_wrapper_xcursor)(unsigned int, const char *, int); +extern XcursorImages *(*XcursorShapeLoadImages_dylibloader_wrapper_xcursor)(unsigned int, const char *, int); +extern Cursor (*XcursorShapeLoadCursor_dylibloader_wrapper_xcursor)(Display *, unsigned int); +extern XcursorCursors *(*XcursorShapeLoadCursors_dylibloader_wrapper_xcursor)(Display *, unsigned int); +extern Cursor (*XcursorTryShapeCursor_dylibloader_wrapper_xcursor)(Display *, Font, Font, unsigned int, unsigned int, const XColor *, const XColor *); +extern void (*XcursorNoticeCreateBitmap_dylibloader_wrapper_xcursor)(Display *, Pixmap, unsigned int, unsigned int); +extern void (*XcursorNoticePutBitmap_dylibloader_wrapper_xcursor)(Display *, Drawable, XImage *); +extern Cursor (*XcursorTryShapeBitmapCursor_dylibloader_wrapper_xcursor)(Display *, Pixmap, Pixmap, XColor *, XColor *, unsigned int, unsigned int); +extern void (*XcursorImageHash_dylibloader_wrapper_xcursor)(XImage *, unsigned char [16]); +extern XcursorBool (*XcursorSupportsARGB_dylibloader_wrapper_xcursor)(Display *); +extern XcursorBool (*XcursorSupportsAnim_dylibloader_wrapper_xcursor)(Display *); +extern XcursorBool (*XcursorSetDefaultSize_dylibloader_wrapper_xcursor)(Display *, int); +extern int (*XcursorGetDefaultSize_dylibloader_wrapper_xcursor)(Display *); +extern XcursorBool (*XcursorSetTheme_dylibloader_wrapper_xcursor)(Display *, const char *); +extern char *(*XcursorGetTheme_dylibloader_wrapper_xcursor)(Display *); +extern XcursorBool (*XcursorGetThemeCore_dylibloader_wrapper_xcursor)(Display *); +extern XcursorBool (*XcursorSetThemeCore_dylibloader_wrapper_xcursor)(Display *, XcursorBool); int initialize_xcursor(int verbose); #ifdef __cplusplus } diff --git a/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c index 4e3349c574..56ae854686 100644 --- a/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c +++ b/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c @@ -1,19 +1,11 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by generate-wrapper.py 0.3 on 2023-01-23 15:11:29 -// flags: generate-wrapper.py --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xext.h" --include ./thirdparty/linuxbsd_headers/X11/extensions/shape.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/shape.h" --soname libXext.so.6 --init-name xext --output-header ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c +// generated by generate-wrapper.py 0.6 on 2024-11-09 02:52:36 +// flags: generate-wrapper.py --sys-include thirdparty/linuxbsd_headers/X11/extensions/Xext.h --include ./thirdparty/linuxbsd_headers/X11/extensions/shape.h --sys-include thirdparty/linuxbsd_headers/X11/extensions/shape.h --soname libXext.so.6 --init-name xext --output-header ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c --ignore-other --implementation-header thirdparty/linuxbsd_headers/X11/Xlib.h // -// NOTE: Generated from Xext 1.3.5. -// This has been handpatched to workaround some issues with the generator that -// will be eventually fixed. In this case, non-existent symbols inherited from -// libX11, but absent in libXext.so.6, were removed and an include needed for -// proper parsing was added (this had also to be temporarily added to the -// original header, as dynload-wrapper would complain otherwise) #include <stdint.h> -// HANDPATCH: Needed for a successful compilation. #include "thirdparty/linuxbsd_headers/X11/Xlib.h" - #define XShapeQueryExtension XShapeQueryExtension_dylibloader_orig_xext #define XShapeQueryVersion XShapeQueryVersion_dylibloader_orig_xext #define XShapeCombineRegion XShapeCombineRegion_dylibloader_orig_xext @@ -40,17 +32,17 @@ #undef XShapeGetRectangles #include <dlfcn.h> #include <stdio.h> -int (*XShapeQueryExtension_dylibloader_wrapper_xext)( Display*, int*, int*); -int (*XShapeQueryVersion_dylibloader_wrapper_xext)( Display*, int*, int*); -void (*XShapeCombineRegion_dylibloader_wrapper_xext)( Display*, Window, int, int, int, Region, int); -void (*XShapeCombineRectangles_dylibloader_wrapper_xext)( Display*, Window, int, int, int, XRectangle*, int, int, int); -void (*XShapeCombineMask_dylibloader_wrapper_xext)( Display*, Window, int, int, int, Pixmap, int); -void (*XShapeCombineShape_dylibloader_wrapper_xext)( Display*, Window, int, int, int, Window, int, int); -void (*XShapeOffsetShape_dylibloader_wrapper_xext)( Display*, Window, int, int, int); -int (*XShapeQueryExtents_dylibloader_wrapper_xext)( Display*, Window, int*, int*, int*, unsigned int*, unsigned int*, int*, int*, int*, unsigned int*, unsigned int*); -void (*XShapeSelectInput_dylibloader_wrapper_xext)( Display*, Window, unsigned long); -unsigned long (*XShapeInputSelected_dylibloader_wrapper_xext)( Display*, Window); -XRectangle* (*XShapeGetRectangles_dylibloader_wrapper_xext)( Display*, Window, int, int*, int*); +int (*XShapeQueryExtension_dylibloader_wrapper_xext)(Display *, int *, int *); +int (*XShapeQueryVersion_dylibloader_wrapper_xext)(Display *, int *, int *); +void (*XShapeCombineRegion_dylibloader_wrapper_xext)(Display *, Window, int, int, int, Region, int); +void (*XShapeCombineRectangles_dylibloader_wrapper_xext)(Display *, Window, int, int, int, XRectangle *, int, int, int); +void (*XShapeCombineMask_dylibloader_wrapper_xext)(Display *, Window, int, int, int, Pixmap, int); +void (*XShapeCombineShape_dylibloader_wrapper_xext)(Display *, Window, int, int, int, Window, int, int); +void (*XShapeOffsetShape_dylibloader_wrapper_xext)(Display *, Window, int, int, int); +int (*XShapeQueryExtents_dylibloader_wrapper_xext)(Display *, Window, int *, int *, int *, unsigned int *, unsigned int *, int *, int *, int *, unsigned int *, unsigned int *); +void (*XShapeSelectInput_dylibloader_wrapper_xext)(Display *, Window, unsigned long); +unsigned long (*XShapeInputSelected_dylibloader_wrapper_xext)(Display *, Window); +XRectangle *(*XShapeGetRectangles_dylibloader_wrapper_xext)(Display *, Window, int, int *, int *); int initialize_xext(int verbose) { void *handle; char *error; diff --git a/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h index e535756d82..ecce399d09 100644 --- a/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h +++ b/platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h @@ -2,20 +2,11 @@ #define DYLIBLOAD_WRAPPER_XEXT // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by generate-wrapper.py 0.3 on 2023-01-23 15:11:29 -// flags: generate-wrapper.py --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xext.h" --include ./thirdparty/linuxbsd_headers/X11/extensions/shape.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/shape.h" --soname libXext.so.6 --init-name xext --output-header ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c +// generated by generate-wrapper.py 0.6 on 2024-11-09 02:52:36 +// flags: generate-wrapper.py --sys-include thirdparty/linuxbsd_headers/X11/extensions/Xext.h --include ./thirdparty/linuxbsd_headers/X11/extensions/shape.h --sys-include thirdparty/linuxbsd_headers/X11/extensions/shape.h --soname libXext.so.6 --init-name xext --output-header ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xext-so_wrap.c --ignore-other --implementation-header thirdparty/linuxbsd_headers/X11/Xlib.h // -// NOTE: Generated from Xext 1.3.5. -// This has been handpatched to workaround some issues with the generator that -// will be eventually fixed. In this case, non-existent symbols inherited from -// libX11, but absent in libXext.so.6, were removed and an include needed for -// proper parsing was added (this had also to be temporarily added to the -// original header, as dynload-wrapper would complain otherwise) #include <stdint.h> -// HANDPATCH: Needed for a successful compilation. -#include "thirdparty/linuxbsd_headers/X11/Xlib.h" - #define XShapeQueryExtension XShapeQueryExtension_dylibloader_orig_xext #define XShapeQueryVersion XShapeQueryVersion_dylibloader_orig_xext #define XShapeCombineRegion XShapeCombineRegion_dylibloader_orig_xext @@ -54,17 +45,17 @@ extern "C" { #define XShapeSelectInput XShapeSelectInput_dylibloader_wrapper_xext #define XShapeInputSelected XShapeInputSelected_dylibloader_wrapper_xext #define XShapeGetRectangles XShapeGetRectangles_dylibloader_wrapper_xext -extern int (*XShapeQueryExtension_dylibloader_wrapper_xext)( Display*, int*, int*); -extern int (*XShapeQueryVersion_dylibloader_wrapper_xext)( Display*, int*, int*); -extern void (*XShapeCombineRegion_dylibloader_wrapper_xext)( Display*, Window, int, int, int, Region, int); -extern void (*XShapeCombineRectangles_dylibloader_wrapper_xext)( Display*, Window, int, int, int, XRectangle*, int, int, int); -extern void (*XShapeCombineMask_dylibloader_wrapper_xext)( Display*, Window, int, int, int, Pixmap, int); -extern void (*XShapeCombineShape_dylibloader_wrapper_xext)( Display*, Window, int, int, int, Window, int, int); -extern void (*XShapeOffsetShape_dylibloader_wrapper_xext)( Display*, Window, int, int, int); -extern int (*XShapeQueryExtents_dylibloader_wrapper_xext)( Display*, Window, int*, int*, int*, unsigned int*, unsigned int*, int*, int*, int*, unsigned int*, unsigned int*); -extern void (*XShapeSelectInput_dylibloader_wrapper_xext)( Display*, Window, unsigned long); -extern unsigned long (*XShapeInputSelected_dylibloader_wrapper_xext)( Display*, Window); -extern XRectangle* (*XShapeGetRectangles_dylibloader_wrapper_xext)( Display*, Window, int, int*, int*); +extern int (*XShapeQueryExtension_dylibloader_wrapper_xext)(Display *, int *, int *); +extern int (*XShapeQueryVersion_dylibloader_wrapper_xext)(Display *, int *, int *); +extern void (*XShapeCombineRegion_dylibloader_wrapper_xext)(Display *, Window, int, int, int, Region, int); +extern void (*XShapeCombineRectangles_dylibloader_wrapper_xext)(Display *, Window, int, int, int, XRectangle *, int, int, int); +extern void (*XShapeCombineMask_dylibloader_wrapper_xext)(Display *, Window, int, int, int, Pixmap, int); +extern void (*XShapeCombineShape_dylibloader_wrapper_xext)(Display *, Window, int, int, int, Window, int, int); +extern void (*XShapeOffsetShape_dylibloader_wrapper_xext)(Display *, Window, int, int, int); +extern int (*XShapeQueryExtents_dylibloader_wrapper_xext)(Display *, Window, int *, int *, int *, unsigned int *, unsigned int *, int *, int *, int *, unsigned int *, unsigned int *); +extern void (*XShapeSelectInput_dylibloader_wrapper_xext)(Display *, Window, unsigned long); +extern unsigned long (*XShapeInputSelected_dylibloader_wrapper_xext)(Display *, Window); +extern XRectangle *(*XShapeGetRectangles_dylibloader_wrapper_xext)(Display *, Window, int, int *, int *); int initialize_xext(int verbose); #ifdef __cplusplus } diff --git a/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c index 850ed1fc6b..eeb6bf7a8f 100644 --- a/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c +++ b/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c @@ -1,12 +1,8 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by generate-wrapper.py 0.3 on 2023-01-23 15:11:35 -// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h" --soname libXinerama.so.1 --init-name xinerama --output-header ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c +// generated by generate-wrapper.py 0.6 on 2024-11-09 02:52:36 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h --sys-include thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h --soname libXinerama.so.1 --init-name xinerama --output-header ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c --ignore-other // -// NOTE: Generated from Xinerama 1.1.4. -// This has been handpatched to workaround some issues with the generator that -// will be eventually fixed. In this case, non-existent symbols inherited from -// libX11, but absent in libXinerama.so.1, were removed. #include <stdint.h> #define XineramaQueryExtension XineramaQueryExtension_dylibloader_orig_xinerama @@ -20,10 +16,10 @@ #undef XineramaQueryScreens #include <dlfcn.h> #include <stdio.h> -int (*XineramaQueryExtension_dylibloader_wrapper_xinerama)( Display*, int*, int*); -int (*XineramaQueryVersion_dylibloader_wrapper_xinerama)( Display*, int*, int*); -int (*XineramaIsActive_dylibloader_wrapper_xinerama)( Display*); -XineramaScreenInfo* (*XineramaQueryScreens_dylibloader_wrapper_xinerama)( Display*, int*); +int (*XineramaQueryExtension_dylibloader_wrapper_xinerama)(Display *, int *, int *); +int (*XineramaQueryVersion_dylibloader_wrapper_xinerama)(Display *, int *, int *); +int (*XineramaIsActive_dylibloader_wrapper_xinerama)(Display *); +XineramaScreenInfo *(*XineramaQueryScreens_dylibloader_wrapper_xinerama)(Display *, int *); int initialize_xinerama(int verbose) { void *handle; char *error; diff --git a/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h index e3cedfc8ad..b421a0ecf5 100644 --- a/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h +++ b/platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h @@ -2,13 +2,9 @@ #define DYLIBLOAD_WRAPPER_XINERAMA // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by generate-wrapper.py 0.3 on 2023-01-23 15:11:35 -// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h" --soname libXinerama.so.1 --init-name xinerama --output-header ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c +// generated by generate-wrapper.py 0.6 on 2024-11-09 02:52:36 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h --sys-include thirdparty/linuxbsd_headers/X11/extensions/Xinerama.h --soname libXinerama.so.1 --init-name xinerama --output-header ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinerama-so_wrap.c --ignore-other // -// NOTE: Generated from Xinerama 1.1.4. -// This has been handpatched to workaround some issues with the generator that -// will be eventually fixed. In this case, non-existent symbols inherited from -// libX11, but absent in libXinerama.so.1, were removed. #include <stdint.h> #define XineramaQueryExtension XineramaQueryExtension_dylibloader_orig_xinerama @@ -27,10 +23,10 @@ extern "C" { #define XineramaQueryVersion XineramaQueryVersion_dylibloader_wrapper_xinerama #define XineramaIsActive XineramaIsActive_dylibloader_wrapper_xinerama #define XineramaQueryScreens XineramaQueryScreens_dylibloader_wrapper_xinerama -extern int (*XineramaQueryExtension_dylibloader_wrapper_xinerama)( Display*, int*, int*); -extern int (*XineramaQueryVersion_dylibloader_wrapper_xinerama)( Display*, int*, int*); -extern int (*XineramaIsActive_dylibloader_wrapper_xinerama)( Display*); -extern XineramaScreenInfo* (*XineramaQueryScreens_dylibloader_wrapper_xinerama)( Display*, int*); +extern int (*XineramaQueryExtension_dylibloader_wrapper_xinerama)(Display *, int *, int *); +extern int (*XineramaQueryVersion_dylibloader_wrapper_xinerama)(Display *, int *, int *); +extern int (*XineramaIsActive_dylibloader_wrapper_xinerama)(Display *); +extern XineramaScreenInfo *(*XineramaQueryScreens_dylibloader_wrapper_xinerama)(Display *, int *); int initialize_xinerama(int verbose); #ifdef __cplusplus } diff --git a/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c index fc08b97e3c..8f031acb20 100644 --- a/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c +++ b/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c @@ -1,12 +1,8 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by generate-wrapper.py 0.3 on 2023-01-23 15:12:16 -// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/XInput2.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/XInput2.h" --soname libXi.so.6 --init-name xinput2 --output-header ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c +// generated by generate-wrapper.py 0.6 on 2024-11-09 02:52:36 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/XInput2.h --sys-include thirdparty/linuxbsd_headers/X11/extensions/XInput2.h --soname libXi.so.6 --init-name xinput2 --output-header ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c --ignore-other // -// NOTE: Generated from Xi 1.7.10. -// This has been handpatched to workaround some issues with the generator that -// will be eventually fixed. In this case, non-existent symbols inherited from -// libX11, liXext and libXfixes, but absent in libXi.so.6, were removed. #include <stdint.h> #define XIQueryPointer XIQueryPointer_dylibloader_orig_xinput2 @@ -80,40 +76,40 @@ #undef XIFreeDeviceInfo #include <dlfcn.h> #include <stdio.h> -int (*XIQueryPointer_dylibloader_wrapper_xinput2)( Display*, int, Window, Window*, Window*, double*, double*, double*, double*, XIButtonState*, XIModifierState*, XIGroupState*); -int (*XIWarpPointer_dylibloader_wrapper_xinput2)( Display*, int, Window, Window, double, double, unsigned int, unsigned int, double, double); -int (*XIDefineCursor_dylibloader_wrapper_xinput2)( Display*, int, Window, Cursor); -int (*XIUndefineCursor_dylibloader_wrapper_xinput2)( Display*, int, Window); -int (*XIChangeHierarchy_dylibloader_wrapper_xinput2)( Display*, XIAnyHierarchyChangeInfo*, int); -int (*XISetClientPointer_dylibloader_wrapper_xinput2)( Display*, Window, int); -int (*XIGetClientPointer_dylibloader_wrapper_xinput2)( Display*, Window, int*); -int (*XISelectEvents_dylibloader_wrapper_xinput2)( Display*, Window, XIEventMask*, int); -XIEventMask* (*XIGetSelectedEvents_dylibloader_wrapper_xinput2)( Display*, Window, int*); -int (*XIQueryVersion_dylibloader_wrapper_xinput2)( Display*, int*, int*); -XIDeviceInfo* (*XIQueryDevice_dylibloader_wrapper_xinput2)( Display*, int, int*); -int (*XISetFocus_dylibloader_wrapper_xinput2)( Display*, int, Window, Time); -int (*XIGetFocus_dylibloader_wrapper_xinput2)( Display*, int, Window*); -int (*XIGrabDevice_dylibloader_wrapper_xinput2)( Display*, int, Window, Time, Cursor, int, int, int, XIEventMask*); -int (*XIUngrabDevice_dylibloader_wrapper_xinput2)( Display*, int, Time); -int (*XIAllowEvents_dylibloader_wrapper_xinput2)( Display*, int, int, Time); -int (*XIAllowTouchEvents_dylibloader_wrapper_xinput2)( Display*, int, unsigned int, Window, int); -int (*XIGrabButton_dylibloader_wrapper_xinput2)( Display*, int, int, Window, Cursor, int, int, int, XIEventMask*, int, XIGrabModifiers*); -int (*XIGrabKeycode_dylibloader_wrapper_xinput2)( Display*, int, int, Window, int, int, int, XIEventMask*, int, XIGrabModifiers*); -int (*XIGrabEnter_dylibloader_wrapper_xinput2)( Display*, int, Window, Cursor, int, int, int, XIEventMask*, int, XIGrabModifiers*); -int (*XIGrabFocusIn_dylibloader_wrapper_xinput2)( Display*, int, Window, int, int, int, XIEventMask*, int, XIGrabModifiers*); -int (*XIGrabTouchBegin_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIEventMask*, int, XIGrabModifiers*); -int (*XIUngrabButton_dylibloader_wrapper_xinput2)( Display*, int, int, Window, int, XIGrabModifiers*); -int (*XIUngrabKeycode_dylibloader_wrapper_xinput2)( Display*, int, int, Window, int, XIGrabModifiers*); -int (*XIUngrabEnter_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIGrabModifiers*); -int (*XIUngrabFocusIn_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIGrabModifiers*); -int (*XIUngrabTouchBegin_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIGrabModifiers*); -Atom* (*XIListProperties_dylibloader_wrapper_xinput2)( Display*, int, int*); -void (*XIChangeProperty_dylibloader_wrapper_xinput2)( Display*, int, Atom, Atom, int, int, unsigned char*, int); -void (*XIDeleteProperty_dylibloader_wrapper_xinput2)( Display*, int, Atom); -int (*XIGetProperty_dylibloader_wrapper_xinput2)( Display*, int, Atom, long, long, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); -void (*XIBarrierReleasePointers_dylibloader_wrapper_xinput2)( Display*, XIBarrierReleasePointerInfo*, int); -void (*XIBarrierReleasePointer_dylibloader_wrapper_xinput2)( Display*, int, PointerBarrier, BarrierEventID); -void (*XIFreeDeviceInfo_dylibloader_wrapper_xinput2)( XIDeviceInfo*); +int (*XIQueryPointer_dylibloader_wrapper_xinput2)(Display *, int, Window, Window *, Window *, double *, double *, double *, double *, XIButtonState *, XIModifierState *, XIGroupState *); +int (*XIWarpPointer_dylibloader_wrapper_xinput2)(Display *, int, Window, Window, double, double, unsigned int, unsigned int, double, double); +int (*XIDefineCursor_dylibloader_wrapper_xinput2)(Display *, int, Window, Cursor); +int (*XIUndefineCursor_dylibloader_wrapper_xinput2)(Display *, int, Window); +int (*XIChangeHierarchy_dylibloader_wrapper_xinput2)(Display *, XIAnyHierarchyChangeInfo *, int); +int (*XISetClientPointer_dylibloader_wrapper_xinput2)(Display *, Window, int); +int (*XIGetClientPointer_dylibloader_wrapper_xinput2)(Display *, Window, int *); +int (*XISelectEvents_dylibloader_wrapper_xinput2)(Display *, Window, XIEventMask *, int); +XIEventMask *(*XIGetSelectedEvents_dylibloader_wrapper_xinput2)(Display *, Window, int *); +int (*XIQueryVersion_dylibloader_wrapper_xinput2)(Display *, int *, int *); +XIDeviceInfo *(*XIQueryDevice_dylibloader_wrapper_xinput2)(Display *, int, int *); +int (*XISetFocus_dylibloader_wrapper_xinput2)(Display *, int, Window, Time); +int (*XIGetFocus_dylibloader_wrapper_xinput2)(Display *, int, Window *); +int (*XIGrabDevice_dylibloader_wrapper_xinput2)(Display *, int, Window, Time, Cursor, int, int, int, XIEventMask *); +int (*XIUngrabDevice_dylibloader_wrapper_xinput2)(Display *, int, Time); +int (*XIAllowEvents_dylibloader_wrapper_xinput2)(Display *, int, int, Time); +int (*XIAllowTouchEvents_dylibloader_wrapper_xinput2)(Display *, int, unsigned int, Window, int); +int (*XIGrabButton_dylibloader_wrapper_xinput2)(Display *, int, int, Window, Cursor, int, int, int, XIEventMask *, int, XIGrabModifiers *); +int (*XIGrabKeycode_dylibloader_wrapper_xinput2)(Display *, int, int, Window, int, int, int, XIEventMask *, int, XIGrabModifiers *); +int (*XIGrabEnter_dylibloader_wrapper_xinput2)(Display *, int, Window, Cursor, int, int, int, XIEventMask *, int, XIGrabModifiers *); +int (*XIGrabFocusIn_dylibloader_wrapper_xinput2)(Display *, int, Window, int, int, int, XIEventMask *, int, XIGrabModifiers *); +int (*XIGrabTouchBegin_dylibloader_wrapper_xinput2)(Display *, int, Window, int, XIEventMask *, int, XIGrabModifiers *); +int (*XIUngrabButton_dylibloader_wrapper_xinput2)(Display *, int, int, Window, int, XIGrabModifiers *); +int (*XIUngrabKeycode_dylibloader_wrapper_xinput2)(Display *, int, int, Window, int, XIGrabModifiers *); +int (*XIUngrabEnter_dylibloader_wrapper_xinput2)(Display *, int, Window, int, XIGrabModifiers *); +int (*XIUngrabFocusIn_dylibloader_wrapper_xinput2)(Display *, int, Window, int, XIGrabModifiers *); +int (*XIUngrabTouchBegin_dylibloader_wrapper_xinput2)(Display *, int, Window, int, XIGrabModifiers *); +Atom *(*XIListProperties_dylibloader_wrapper_xinput2)(Display *, int, int *); +void (*XIChangeProperty_dylibloader_wrapper_xinput2)(Display *, int, Atom, Atom, int, int, unsigned char *, int); +void (*XIDeleteProperty_dylibloader_wrapper_xinput2)(Display *, int, Atom); +int (*XIGetProperty_dylibloader_wrapper_xinput2)(Display *, int, Atom, long, long, int, Atom, Atom *, int *, unsigned long *, unsigned long *, unsigned char **); +void (*XIBarrierReleasePointers_dylibloader_wrapper_xinput2)(Display *, XIBarrierReleasePointerInfo *, int); +void (*XIBarrierReleasePointer_dylibloader_wrapper_xinput2)(Display *, int, PointerBarrier, BarrierEventID); +void (*XIFreeDeviceInfo_dylibloader_wrapper_xinput2)(XIDeviceInfo *); int initialize_xinput2(int verbose) { void *handle; char *error; diff --git a/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h index 571072c3cd..7c54dc080a 100644 --- a/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h +++ b/platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h @@ -2,13 +2,9 @@ #define DYLIBLOAD_WRAPPER_XINPUT2 // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by generate-wrapper.py 0.3 on 2023-01-23 15:12:16 -// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/XInput2.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/XInput2.h" --soname libXi.so.6 --init-name xinput2 --output-header ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c +// generated by generate-wrapper.py 0.6 on 2024-11-09 02:52:36 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/XInput2.h --sys-include thirdparty/linuxbsd_headers/X11/extensions/XInput2.h --soname libXi.so.6 --init-name xinput2 --output-header ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xinput2-so_wrap.c --ignore-other // -// NOTE: Generated from Xi 1.7.10. -// This has been handpatched to workaround some issues with the generator that -// will be eventually fixed. In this case, non-existent symbols inherited from -// libX11, liXext and libXfixes, but absent in libXi.so.6, were removed. #include <stdint.h> #define XIQueryPointer XIQueryPointer_dylibloader_orig_xinput2 @@ -117,40 +113,40 @@ extern "C" { #define XIBarrierReleasePointers XIBarrierReleasePointers_dylibloader_wrapper_xinput2 #define XIBarrierReleasePointer XIBarrierReleasePointer_dylibloader_wrapper_xinput2 #define XIFreeDeviceInfo XIFreeDeviceInfo_dylibloader_wrapper_xinput2 -extern int (*XIQueryPointer_dylibloader_wrapper_xinput2)( Display*, int, Window, Window*, Window*, double*, double*, double*, double*, XIButtonState*, XIModifierState*, XIGroupState*); -extern int (*XIWarpPointer_dylibloader_wrapper_xinput2)( Display*, int, Window, Window, double, double, unsigned int, unsigned int, double, double); -extern int (*XIDefineCursor_dylibloader_wrapper_xinput2)( Display*, int, Window, Cursor); -extern int (*XIUndefineCursor_dylibloader_wrapper_xinput2)( Display*, int, Window); -extern int (*XIChangeHierarchy_dylibloader_wrapper_xinput2)( Display*, XIAnyHierarchyChangeInfo*, int); -extern int (*XISetClientPointer_dylibloader_wrapper_xinput2)( Display*, Window, int); -extern int (*XIGetClientPointer_dylibloader_wrapper_xinput2)( Display*, Window, int*); -extern int (*XISelectEvents_dylibloader_wrapper_xinput2)( Display*, Window, XIEventMask*, int); -extern XIEventMask* (*XIGetSelectedEvents_dylibloader_wrapper_xinput2)( Display*, Window, int*); -extern int (*XIQueryVersion_dylibloader_wrapper_xinput2)( Display*, int*, int*); -extern XIDeviceInfo* (*XIQueryDevice_dylibloader_wrapper_xinput2)( Display*, int, int*); -extern int (*XISetFocus_dylibloader_wrapper_xinput2)( Display*, int, Window, Time); -extern int (*XIGetFocus_dylibloader_wrapper_xinput2)( Display*, int, Window*); -extern int (*XIGrabDevice_dylibloader_wrapper_xinput2)( Display*, int, Window, Time, Cursor, int, int, int, XIEventMask*); -extern int (*XIUngrabDevice_dylibloader_wrapper_xinput2)( Display*, int, Time); -extern int (*XIAllowEvents_dylibloader_wrapper_xinput2)( Display*, int, int, Time); -extern int (*XIAllowTouchEvents_dylibloader_wrapper_xinput2)( Display*, int, unsigned int, Window, int); -extern int (*XIGrabButton_dylibloader_wrapper_xinput2)( Display*, int, int, Window, Cursor, int, int, int, XIEventMask*, int, XIGrabModifiers*); -extern int (*XIGrabKeycode_dylibloader_wrapper_xinput2)( Display*, int, int, Window, int, int, int, XIEventMask*, int, XIGrabModifiers*); -extern int (*XIGrabEnter_dylibloader_wrapper_xinput2)( Display*, int, Window, Cursor, int, int, int, XIEventMask*, int, XIGrabModifiers*); -extern int (*XIGrabFocusIn_dylibloader_wrapper_xinput2)( Display*, int, Window, int, int, int, XIEventMask*, int, XIGrabModifiers*); -extern int (*XIGrabTouchBegin_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIEventMask*, int, XIGrabModifiers*); -extern int (*XIUngrabButton_dylibloader_wrapper_xinput2)( Display*, int, int, Window, int, XIGrabModifiers*); -extern int (*XIUngrabKeycode_dylibloader_wrapper_xinput2)( Display*, int, int, Window, int, XIGrabModifiers*); -extern int (*XIUngrabEnter_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIGrabModifiers*); -extern int (*XIUngrabFocusIn_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIGrabModifiers*); -extern int (*XIUngrabTouchBegin_dylibloader_wrapper_xinput2)( Display*, int, Window, int, XIGrabModifiers*); -extern Atom* (*XIListProperties_dylibloader_wrapper_xinput2)( Display*, int, int*); -extern void (*XIChangeProperty_dylibloader_wrapper_xinput2)( Display*, int, Atom, Atom, int, int, unsigned char*, int); -extern void (*XIDeleteProperty_dylibloader_wrapper_xinput2)( Display*, int, Atom); -extern int (*XIGetProperty_dylibloader_wrapper_xinput2)( Display*, int, Atom, long, long, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); -extern void (*XIBarrierReleasePointers_dylibloader_wrapper_xinput2)( Display*, XIBarrierReleasePointerInfo*, int); -extern void (*XIBarrierReleasePointer_dylibloader_wrapper_xinput2)( Display*, int, PointerBarrier, BarrierEventID); -extern void (*XIFreeDeviceInfo_dylibloader_wrapper_xinput2)( XIDeviceInfo*); +extern int (*XIQueryPointer_dylibloader_wrapper_xinput2)(Display *, int, Window, Window *, Window *, double *, double *, double *, double *, XIButtonState *, XIModifierState *, XIGroupState *); +extern int (*XIWarpPointer_dylibloader_wrapper_xinput2)(Display *, int, Window, Window, double, double, unsigned int, unsigned int, double, double); +extern int (*XIDefineCursor_dylibloader_wrapper_xinput2)(Display *, int, Window, Cursor); +extern int (*XIUndefineCursor_dylibloader_wrapper_xinput2)(Display *, int, Window); +extern int (*XIChangeHierarchy_dylibloader_wrapper_xinput2)(Display *, XIAnyHierarchyChangeInfo *, int); +extern int (*XISetClientPointer_dylibloader_wrapper_xinput2)(Display *, Window, int); +extern int (*XIGetClientPointer_dylibloader_wrapper_xinput2)(Display *, Window, int *); +extern int (*XISelectEvents_dylibloader_wrapper_xinput2)(Display *, Window, XIEventMask *, int); +extern XIEventMask *(*XIGetSelectedEvents_dylibloader_wrapper_xinput2)(Display *, Window, int *); +extern int (*XIQueryVersion_dylibloader_wrapper_xinput2)(Display *, int *, int *); +extern XIDeviceInfo *(*XIQueryDevice_dylibloader_wrapper_xinput2)(Display *, int, int *); +extern int (*XISetFocus_dylibloader_wrapper_xinput2)(Display *, int, Window, Time); +extern int (*XIGetFocus_dylibloader_wrapper_xinput2)(Display *, int, Window *); +extern int (*XIGrabDevice_dylibloader_wrapper_xinput2)(Display *, int, Window, Time, Cursor, int, int, int, XIEventMask *); +extern int (*XIUngrabDevice_dylibloader_wrapper_xinput2)(Display *, int, Time); +extern int (*XIAllowEvents_dylibloader_wrapper_xinput2)(Display *, int, int, Time); +extern int (*XIAllowTouchEvents_dylibloader_wrapper_xinput2)(Display *, int, unsigned int, Window, int); +extern int (*XIGrabButton_dylibloader_wrapper_xinput2)(Display *, int, int, Window, Cursor, int, int, int, XIEventMask *, int, XIGrabModifiers *); +extern int (*XIGrabKeycode_dylibloader_wrapper_xinput2)(Display *, int, int, Window, int, int, int, XIEventMask *, int, XIGrabModifiers *); +extern int (*XIGrabEnter_dylibloader_wrapper_xinput2)(Display *, int, Window, Cursor, int, int, int, XIEventMask *, int, XIGrabModifiers *); +extern int (*XIGrabFocusIn_dylibloader_wrapper_xinput2)(Display *, int, Window, int, int, int, XIEventMask *, int, XIGrabModifiers *); +extern int (*XIGrabTouchBegin_dylibloader_wrapper_xinput2)(Display *, int, Window, int, XIEventMask *, int, XIGrabModifiers *); +extern int (*XIUngrabButton_dylibloader_wrapper_xinput2)(Display *, int, int, Window, int, XIGrabModifiers *); +extern int (*XIUngrabKeycode_dylibloader_wrapper_xinput2)(Display *, int, int, Window, int, XIGrabModifiers *); +extern int (*XIUngrabEnter_dylibloader_wrapper_xinput2)(Display *, int, Window, int, XIGrabModifiers *); +extern int (*XIUngrabFocusIn_dylibloader_wrapper_xinput2)(Display *, int, Window, int, XIGrabModifiers *); +extern int (*XIUngrabTouchBegin_dylibloader_wrapper_xinput2)(Display *, int, Window, int, XIGrabModifiers *); +extern Atom *(*XIListProperties_dylibloader_wrapper_xinput2)(Display *, int, int *); +extern void (*XIChangeProperty_dylibloader_wrapper_xinput2)(Display *, int, Atom, Atom, int, int, unsigned char *, int); +extern void (*XIDeleteProperty_dylibloader_wrapper_xinput2)(Display *, int, Atom); +extern int (*XIGetProperty_dylibloader_wrapper_xinput2)(Display *, int, Atom, long, long, int, Atom, Atom *, int *, unsigned long *, unsigned long *, unsigned char **); +extern void (*XIBarrierReleasePointers_dylibloader_wrapper_xinput2)(Display *, XIBarrierReleasePointerInfo *, int); +extern void (*XIBarrierReleasePointer_dylibloader_wrapper_xinput2)(Display *, int, PointerBarrier, BarrierEventID); +extern void (*XIFreeDeviceInfo_dylibloader_wrapper_xinput2)(XIDeviceInfo *); int initialize_xinput2(int verbose); #ifdef __cplusplus } diff --git a/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c index d2838569b0..8500f20198 100644 --- a/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c +++ b/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c @@ -1,14 +1,8 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by generate-wrapper.py 0.3 on 2023-01-23 15:13:26 -// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xlib.h --include ./thirdparty/linuxbsd_headers/X11/Xutil.h --include ./thirdparty/linuxbsd_headers/X11/XKBlib.h --sys-include "thirdparty/linuxbsd_headers/X11/Xlib.h" --sys-include "thirdparty/linuxbsd_headers/X11/Xutil.h" --sys-include "thirdparty/linuxbsd_headers/X11/XKBlib.h" --soname libX11.so.6 --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c~ +// generated by generate-wrapper.py 0.6 on 2024-11-09 02:52:36 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xlib.h --include ./thirdparty/linuxbsd_headers/X11/Xutil.h --include ./thirdparty/linuxbsd_headers/X11/XKBlib.h --sys-include thirdparty/linuxbsd_headers/X11/Xlib.h --sys-include thirdparty/linuxbsd_headers/X11/Xutil.h --sys-include thirdparty/linuxbsd_headers/X11/XKBlib.h --soname libX11.so.6 --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c // -// NOTE: Generated from Xlib 1.6.9. -// This has been handpatched to workaround some issues with the generator that -// will be eventually fixed. In this case, the type of the third argument of -// XIfEvent, XPeekIfEvent and XCheckIfEvent had to be fixed as it wasn't parsed -// fully (it's a Bool function pointer, but it was just being parsed as an int -// pointer). #include <stdint.h> #define _Xmblen _Xmblen_dylibloader_orig_xlib @@ -100,6 +94,7 @@ #define XScreenNumberOfScreen XScreenNumberOfScreen_dylibloader_orig_xlib #define XSetErrorHandler XSetErrorHandler_dylibloader_orig_xlib #define XSetIOErrorHandler XSetIOErrorHandler_dylibloader_orig_xlib +#define XSetIOErrorExitHandler XSetIOErrorExitHandler_dylibloader_orig_xlib #define XListPixmapFormats XListPixmapFormats_dylibloader_orig_xlib #define XListDepths XListDepths_dylibloader_orig_xlib #define XReconfigureWMWindow XReconfigureWMWindow_dylibloader_orig_xlib @@ -423,6 +418,7 @@ #define _Xwctomb _Xwctomb_dylibloader_orig_xlib #define XGetEventData XGetEventData_dylibloader_orig_xlib #define XFreeEventData XFreeEventData_dylibloader_orig_xlib +#define XFreeThreads XFreeThreads_dylibloader_orig_xlib #define XAllocClassHint XAllocClassHint_dylibloader_orig_xlib #define XAllocIconSize XAllocIconSize_dylibloader_orig_xlib #define XAllocSizeHints XAllocSizeHints_dylibloader_orig_xlib @@ -706,6 +702,7 @@ #undef XScreenNumberOfScreen #undef XSetErrorHandler #undef XSetIOErrorHandler +#undef XSetIOErrorExitHandler #undef XListPixmapFormats #undef XListDepths #undef XReconfigureWMWindow @@ -1029,6 +1026,7 @@ #undef _Xwctomb #undef XGetEventData #undef XFreeEventData +#undef XFreeThreads #undef XAllocClassHint #undef XAllocIconSize #undef XAllocSizeHints @@ -1222,609 +1220,611 @@ #undef XkbUpdateKeyTypeVirtualMods #include <dlfcn.h> #include <stdio.h> -int (*_Xmblen_dylibloader_wrapper_xlib)( char*, int); -XFontStruct* (*XLoadQueryFont_dylibloader_wrapper_xlib)( Display*,const char*); -XFontStruct* (*XQueryFont_dylibloader_wrapper_xlib)( Display*, XID); -XTimeCoord* (*XGetMotionEvents_dylibloader_wrapper_xlib)( Display*, Window, Time, Time, int*); -XModifierKeymap* (*XDeleteModifiermapEntry_dylibloader_wrapper_xlib)( XModifierKeymap*, KeyCode, int); -XModifierKeymap* (*XGetModifierMapping_dylibloader_wrapper_xlib)( Display*); -XModifierKeymap* (*XInsertModifiermapEntry_dylibloader_wrapper_xlib)( XModifierKeymap*, KeyCode, int); -XModifierKeymap* (*XNewModifiermap_dylibloader_wrapper_xlib)( int); -XImage* (*XCreateImage_dylibloader_wrapper_xlib)( Display*, Visual*, unsigned int, int, int, char*, unsigned int, unsigned int, int, int); -int (*XInitImage_dylibloader_wrapper_xlib)( XImage*); -XImage* (*XGetImage_dylibloader_wrapper_xlib)( Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int); -XImage* (*XGetSubImage_dylibloader_wrapper_xlib)( Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int, XImage*, int, int); -Display* (*XOpenDisplay_dylibloader_wrapper_xlib)(const char*); -void (*XrmInitialize_dylibloader_wrapper_xlib)( void); -char* (*XFetchBytes_dylibloader_wrapper_xlib)( Display*, int*); -char* (*XFetchBuffer_dylibloader_wrapper_xlib)( Display*, int*, int); -char* (*XGetAtomName_dylibloader_wrapper_xlib)( Display*, Atom); -int (*XGetAtomNames_dylibloader_wrapper_xlib)( Display*, Atom*, int, char**); -char* (*XGetDefault_dylibloader_wrapper_xlib)( Display*,const char*,const char*); -char* (*XDisplayName_dylibloader_wrapper_xlib)(const char*); -char* (*XKeysymToString_dylibloader_wrapper_xlib)( KeySym); -int* (*XSynchronize_dylibloader_wrapper_xlib)( Display*, int); -int* (*XSetAfterFunction_dylibloader_wrapper_xlib)( Display*, int*); -Atom (*XInternAtom_dylibloader_wrapper_xlib)( Display*,const char*, int); -int (*XInternAtoms_dylibloader_wrapper_xlib)( Display*, char**, int, int, Atom*); -Colormap (*XCopyColormapAndFree_dylibloader_wrapper_xlib)( Display*, Colormap); -Colormap (*XCreateColormap_dylibloader_wrapper_xlib)( Display*, Window, Visual*, int); -Cursor (*XCreatePixmapCursor_dylibloader_wrapper_xlib)( Display*, Pixmap, Pixmap, XColor*, XColor*, unsigned int, unsigned int); -Cursor (*XCreateGlyphCursor_dylibloader_wrapper_xlib)( Display*, Font, Font, unsigned int, unsigned int,const XColor*,const XColor*); -Cursor (*XCreateFontCursor_dylibloader_wrapper_xlib)( Display*, unsigned int); -Font (*XLoadFont_dylibloader_wrapper_xlib)( Display*,const char*); -GC (*XCreateGC_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned long, XGCValues*); -GContext (*XGContextFromGC_dylibloader_wrapper_xlib)( GC); -void (*XFlushGC_dylibloader_wrapper_xlib)( Display*, GC); -Pixmap (*XCreatePixmap_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int); -Pixmap (*XCreateBitmapFromData_dylibloader_wrapper_xlib)( Display*, Drawable,const char*, unsigned int, unsigned int); -Pixmap (*XCreatePixmapFromBitmapData_dylibloader_wrapper_xlib)( Display*, Drawable, char*, unsigned int, unsigned int, unsigned long, unsigned long, unsigned int); -Window (*XCreateSimpleWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int, unsigned int, unsigned long, unsigned long); -Window (*XGetSelectionOwner_dylibloader_wrapper_xlib)( Display*, Atom); -Window (*XCreateWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual*, unsigned long, XSetWindowAttributes*); -Colormap* (*XListInstalledColormaps_dylibloader_wrapper_xlib)( Display*, Window, int*); -char** (*XListFonts_dylibloader_wrapper_xlib)( Display*,const char*, int, int*); -char** (*XListFontsWithInfo_dylibloader_wrapper_xlib)( Display*,const char*, int, int*, XFontStruct**); -char** (*XGetFontPath_dylibloader_wrapper_xlib)( Display*, int*); -char** (*XListExtensions_dylibloader_wrapper_xlib)( Display*, int*); -Atom* (*XListProperties_dylibloader_wrapper_xlib)( Display*, Window, int*); -XHostAddress* (*XListHosts_dylibloader_wrapper_xlib)( Display*, int*, int*); -KeySym (*XKeycodeToKeysym_dylibloader_wrapper_xlib)( Display*, KeyCode, int); -KeySym (*XLookupKeysym_dylibloader_wrapper_xlib)( XKeyEvent*, int); -KeySym* (*XGetKeyboardMapping_dylibloader_wrapper_xlib)( Display*, KeyCode, int, int*); -KeySym (*XStringToKeysym_dylibloader_wrapper_xlib)(const char*); -long (*XMaxRequestSize_dylibloader_wrapper_xlib)( Display*); -long (*XExtendedMaxRequestSize_dylibloader_wrapper_xlib)( Display*); -char* (*XResourceManagerString_dylibloader_wrapper_xlib)( Display*); -char* (*XScreenResourceString_dylibloader_wrapper_xlib)( Screen*); -unsigned long (*XDisplayMotionBufferSize_dylibloader_wrapper_xlib)( Display*); -VisualID (*XVisualIDFromVisual_dylibloader_wrapper_xlib)( Visual*); -int (*XInitThreads_dylibloader_wrapper_xlib)( void); -void (*XLockDisplay_dylibloader_wrapper_xlib)( Display*); -void (*XUnlockDisplay_dylibloader_wrapper_xlib)( Display*); -XExtCodes* (*XInitExtension_dylibloader_wrapper_xlib)( Display*,const char*); -XExtCodes* (*XAddExtension_dylibloader_wrapper_xlib)( Display*); -XExtData* (*XFindOnExtensionList_dylibloader_wrapper_xlib)( XExtData**, int); -XExtData** (*XEHeadOfExtensionList_dylibloader_wrapper_xlib)( XEDataObject); -Window (*XRootWindow_dylibloader_wrapper_xlib)( Display*, int); -Window (*XDefaultRootWindow_dylibloader_wrapper_xlib)( Display*); -Window (*XRootWindowOfScreen_dylibloader_wrapper_xlib)( Screen*); -Visual* (*XDefaultVisual_dylibloader_wrapper_xlib)( Display*, int); -Visual* (*XDefaultVisualOfScreen_dylibloader_wrapper_xlib)( Screen*); -GC (*XDefaultGC_dylibloader_wrapper_xlib)( Display*, int); -GC (*XDefaultGCOfScreen_dylibloader_wrapper_xlib)( Screen*); -unsigned long (*XBlackPixel_dylibloader_wrapper_xlib)( Display*, int); -unsigned long (*XWhitePixel_dylibloader_wrapper_xlib)( Display*, int); -unsigned long (*XAllPlanes_dylibloader_wrapper_xlib)( void); -unsigned long (*XBlackPixelOfScreen_dylibloader_wrapper_xlib)( Screen*); -unsigned long (*XWhitePixelOfScreen_dylibloader_wrapper_xlib)( Screen*); -unsigned long (*XNextRequest_dylibloader_wrapper_xlib)( Display*); -unsigned long (*XLastKnownRequestProcessed_dylibloader_wrapper_xlib)( Display*); -char* (*XServerVendor_dylibloader_wrapper_xlib)( Display*); -char* (*XDisplayString_dylibloader_wrapper_xlib)( Display*); -Colormap (*XDefaultColormap_dylibloader_wrapper_xlib)( Display*, int); -Colormap (*XDefaultColormapOfScreen_dylibloader_wrapper_xlib)( Screen*); -Display* (*XDisplayOfScreen_dylibloader_wrapper_xlib)( Screen*); -Screen* (*XScreenOfDisplay_dylibloader_wrapper_xlib)( Display*, int); -Screen* (*XDefaultScreenOfDisplay_dylibloader_wrapper_xlib)( Display*); -long (*XEventMaskOfScreen_dylibloader_wrapper_xlib)( Screen*); -int (*XScreenNumberOfScreen_dylibloader_wrapper_xlib)( Screen*); -XErrorHandler (*XSetErrorHandler_dylibloader_wrapper_xlib)( XErrorHandler); -XIOErrorHandler (*XSetIOErrorHandler_dylibloader_wrapper_xlib)( XIOErrorHandler); -XPixmapFormatValues* (*XListPixmapFormats_dylibloader_wrapper_xlib)( Display*, int*); -int* (*XListDepths_dylibloader_wrapper_xlib)( Display*, int, int*); -int (*XReconfigureWMWindow_dylibloader_wrapper_xlib)( Display*, Window, int, unsigned int, XWindowChanges*); -int (*XGetWMProtocols_dylibloader_wrapper_xlib)( Display*, Window, Atom**, int*); -int (*XSetWMProtocols_dylibloader_wrapper_xlib)( Display*, Window, Atom*, int); -int (*XIconifyWindow_dylibloader_wrapper_xlib)( Display*, Window, int); -int (*XWithdrawWindow_dylibloader_wrapper_xlib)( Display*, Window, int); -int (*XGetCommand_dylibloader_wrapper_xlib)( Display*, Window, char***, int*); -int (*XGetWMColormapWindows_dylibloader_wrapper_xlib)( Display*, Window, Window**, int*); -int (*XSetWMColormapWindows_dylibloader_wrapper_xlib)( Display*, Window, Window*, int); -void (*XFreeStringList_dylibloader_wrapper_xlib)( char**); -int (*XSetTransientForHint_dylibloader_wrapper_xlib)( Display*, Window, Window); -int (*XActivateScreenSaver_dylibloader_wrapper_xlib)( Display*); -int (*XAddHost_dylibloader_wrapper_xlib)( Display*, XHostAddress*); -int (*XAddHosts_dylibloader_wrapper_xlib)( Display*, XHostAddress*, int); -int (*XAddToExtensionList_dylibloader_wrapper_xlib)(struct _XExtData**, XExtData*); -int (*XAddToSaveSet_dylibloader_wrapper_xlib)( Display*, Window); -int (*XAllocColor_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*); -int (*XAllocColorCells_dylibloader_wrapper_xlib)( Display*, Colormap, int, unsigned long*, unsigned int, unsigned long*, unsigned int); -int (*XAllocColorPlanes_dylibloader_wrapper_xlib)( Display*, Colormap, int, unsigned long*, int, int, int, int, unsigned long*, unsigned long*, unsigned long*); -int (*XAllocNamedColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, XColor*, XColor*); -int (*XAllowEvents_dylibloader_wrapper_xlib)( Display*, int, Time); -int (*XAutoRepeatOff_dylibloader_wrapper_xlib)( Display*); -int (*XAutoRepeatOn_dylibloader_wrapper_xlib)( Display*); -int (*XBell_dylibloader_wrapper_xlib)( Display*, int); -int (*XBitmapBitOrder_dylibloader_wrapper_xlib)( Display*); -int (*XBitmapPad_dylibloader_wrapper_xlib)( Display*); -int (*XBitmapUnit_dylibloader_wrapper_xlib)( Display*); -int (*XCellsOfScreen_dylibloader_wrapper_xlib)( Screen*); -int (*XChangeActivePointerGrab_dylibloader_wrapper_xlib)( Display*, unsigned int, Cursor, Time); -int (*XChangeGC_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, XGCValues*); -int (*XChangeKeyboardControl_dylibloader_wrapper_xlib)( Display*, unsigned long, XKeyboardControl*); -int (*XChangeKeyboardMapping_dylibloader_wrapper_xlib)( Display*, int, int, KeySym*, int); -int (*XChangePointerControl_dylibloader_wrapper_xlib)( Display*, int, int, int, int, int); -int (*XChangeProperty_dylibloader_wrapper_xlib)( Display*, Window, Atom, Atom, int, int,const unsigned char*, int); -int (*XChangeSaveSet_dylibloader_wrapper_xlib)( Display*, Window, int); -int (*XChangeWindowAttributes_dylibloader_wrapper_xlib)( Display*, Window, unsigned long, XSetWindowAttributes*); -int (*XCheckIfEvent_dylibloader_wrapper_xlib)( Display*, XEvent*, Bool (*) (Display*, XEvent*, XPointer), XPointer); -int (*XCheckMaskEvent_dylibloader_wrapper_xlib)( Display*, long, XEvent*); -int (*XCheckTypedEvent_dylibloader_wrapper_xlib)( Display*, int, XEvent*); -int (*XCheckTypedWindowEvent_dylibloader_wrapper_xlib)( Display*, Window, int, XEvent*); -int (*XCheckWindowEvent_dylibloader_wrapper_xlib)( Display*, Window, long, XEvent*); -int (*XCirculateSubwindows_dylibloader_wrapper_xlib)( Display*, Window, int); -int (*XCirculateSubwindowsDown_dylibloader_wrapper_xlib)( Display*, Window); -int (*XCirculateSubwindowsUp_dylibloader_wrapper_xlib)( Display*, Window); -int (*XClearArea_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int, int); -int (*XClearWindow_dylibloader_wrapper_xlib)( Display*, Window); -int (*XCloseDisplay_dylibloader_wrapper_xlib)( Display*); -int (*XConfigureWindow_dylibloader_wrapper_xlib)( Display*, Window, unsigned int, XWindowChanges*); -int (*XConnectionNumber_dylibloader_wrapper_xlib)( Display*); -int (*XConvertSelection_dylibloader_wrapper_xlib)( Display*, Atom, Atom, Atom, Window, Time); -int (*XCopyArea_dylibloader_wrapper_xlib)( Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int); -int (*XCopyGC_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, GC); -int (*XCopyPlane_dylibloader_wrapper_xlib)( Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int, unsigned long); -int (*XDefaultDepth_dylibloader_wrapper_xlib)( Display*, int); -int (*XDefaultDepthOfScreen_dylibloader_wrapper_xlib)( Screen*); -int (*XDefaultScreen_dylibloader_wrapper_xlib)( Display*); -int (*XDefineCursor_dylibloader_wrapper_xlib)( Display*, Window, Cursor); -int (*XDeleteProperty_dylibloader_wrapper_xlib)( Display*, Window, Atom); -int (*XDestroyWindow_dylibloader_wrapper_xlib)( Display*, Window); -int (*XDestroySubwindows_dylibloader_wrapper_xlib)( Display*, Window); -int (*XDoesBackingStore_dylibloader_wrapper_xlib)( Screen*); -int (*XDoesSaveUnders_dylibloader_wrapper_xlib)( Screen*); -int (*XDisableAccessControl_dylibloader_wrapper_xlib)( Display*); -int (*XDisplayCells_dylibloader_wrapper_xlib)( Display*, int); -int (*XDisplayHeight_dylibloader_wrapper_xlib)( Display*, int); -int (*XDisplayHeightMM_dylibloader_wrapper_xlib)( Display*, int); -int (*XDisplayKeycodes_dylibloader_wrapper_xlib)( Display*, int*, int*); -int (*XDisplayPlanes_dylibloader_wrapper_xlib)( Display*, int); -int (*XDisplayWidth_dylibloader_wrapper_xlib)( Display*, int); -int (*XDisplayWidthMM_dylibloader_wrapper_xlib)( Display*, int); -int (*XDrawArc_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int, int, int); -int (*XDrawArcs_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XArc*, int); -int (*XDrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const char*, int); -int (*XDrawImageString16_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const XChar2b*, int); -int (*XDrawLine_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, int, int); -int (*XDrawLines_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XPoint*, int, int); -int (*XDrawPoint_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int); -int (*XDrawPoints_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XPoint*, int, int); -int (*XDrawRectangle_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int); -int (*XDrawRectangles_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XRectangle*, int); -int (*XDrawSegments_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XSegment*, int); -int (*XDrawString_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const char*, int); -int (*XDrawString16_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const XChar2b*, int); -int (*XDrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XTextItem*, int); -int (*XDrawText16_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XTextItem16*, int); -int (*XEnableAccessControl_dylibloader_wrapper_xlib)( Display*); -int (*XEventsQueued_dylibloader_wrapper_xlib)( Display*, int); -int (*XFetchName_dylibloader_wrapper_xlib)( Display*, Window, char**); -int (*XFillArc_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int, int, int); -int (*XFillArcs_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XArc*, int); -int (*XFillPolygon_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XPoint*, int, int, int); -int (*XFillRectangle_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int); -int (*XFillRectangles_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XRectangle*, int); -int (*XFlush_dylibloader_wrapper_xlib)( Display*); -int (*XForceScreenSaver_dylibloader_wrapper_xlib)( Display*, int); -int (*XFree_dylibloader_wrapper_xlib)( void*); -int (*XFreeColormap_dylibloader_wrapper_xlib)( Display*, Colormap); -int (*XFreeColors_dylibloader_wrapper_xlib)( Display*, Colormap, unsigned long*, int, unsigned long); -int (*XFreeCursor_dylibloader_wrapper_xlib)( Display*, Cursor); -int (*XFreeExtensionList_dylibloader_wrapper_xlib)( char**); -int (*XFreeFont_dylibloader_wrapper_xlib)( Display*, XFontStruct*); -int (*XFreeFontInfo_dylibloader_wrapper_xlib)( char**, XFontStruct*, int); -int (*XFreeFontNames_dylibloader_wrapper_xlib)( char**); -int (*XFreeFontPath_dylibloader_wrapper_xlib)( char**); -int (*XFreeGC_dylibloader_wrapper_xlib)( Display*, GC); -int (*XFreeModifiermap_dylibloader_wrapper_xlib)( XModifierKeymap*); -int (*XFreePixmap_dylibloader_wrapper_xlib)( Display*, Pixmap); -int (*XGeometry_dylibloader_wrapper_xlib)( Display*, int,const char*,const char*, unsigned int, unsigned int, unsigned int, int, int, int*, int*, int*, int*); -int (*XGetErrorDatabaseText_dylibloader_wrapper_xlib)( Display*,const char*,const char*,const char*, char*, int); -int (*XGetErrorText_dylibloader_wrapper_xlib)( Display*, int, char*, int); -int (*XGetFontProperty_dylibloader_wrapper_xlib)( XFontStruct*, Atom, unsigned long*); -int (*XGetGCValues_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, XGCValues*); -int (*XGetGeometry_dylibloader_wrapper_xlib)( Display*, Drawable, Window*, int*, int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*); -int (*XGetIconName_dylibloader_wrapper_xlib)( Display*, Window, char**); -int (*XGetInputFocus_dylibloader_wrapper_xlib)( Display*, Window*, int*); -int (*XGetKeyboardControl_dylibloader_wrapper_xlib)( Display*, XKeyboardState*); -int (*XGetPointerControl_dylibloader_wrapper_xlib)( Display*, int*, int*, int*); -int (*XGetPointerMapping_dylibloader_wrapper_xlib)( Display*, unsigned char*, int); -int (*XGetScreenSaver_dylibloader_wrapper_xlib)( Display*, int*, int*, int*, int*); -int (*XGetTransientForHint_dylibloader_wrapper_xlib)( Display*, Window, Window*); -int (*XGetWindowProperty_dylibloader_wrapper_xlib)( Display*, Window, Atom, long, long, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); -int (*XGetWindowAttributes_dylibloader_wrapper_xlib)( Display*, Window, XWindowAttributes*); -int (*XGrabButton_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, Window, int, unsigned int, int, int, Window, Cursor); -int (*XGrabKey_dylibloader_wrapper_xlib)( Display*, int, unsigned int, Window, int, int, int); -int (*XGrabKeyboard_dylibloader_wrapper_xlib)( Display*, Window, int, int, int, Time); -int (*XGrabPointer_dylibloader_wrapper_xlib)( Display*, Window, int, unsigned int, int, int, Window, Cursor, Time); -int (*XGrabServer_dylibloader_wrapper_xlib)( Display*); -int (*XHeightMMOfScreen_dylibloader_wrapper_xlib)( Screen*); -int (*XHeightOfScreen_dylibloader_wrapper_xlib)( Screen*); -int (*XIfEvent_dylibloader_wrapper_xlib)( Display*, XEvent*, Bool (*) (Display*, XEvent*, XPointer), XPointer); -int (*XImageByteOrder_dylibloader_wrapper_xlib)( Display*); -int (*XInstallColormap_dylibloader_wrapper_xlib)( Display*, Colormap); -KeyCode (*XKeysymToKeycode_dylibloader_wrapper_xlib)( Display*, KeySym); -int (*XKillClient_dylibloader_wrapper_xlib)( Display*, XID); -int (*XLookupColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, XColor*, XColor*); -int (*XLowerWindow_dylibloader_wrapper_xlib)( Display*, Window); -int (*XMapRaised_dylibloader_wrapper_xlib)( Display*, Window); -int (*XMapSubwindows_dylibloader_wrapper_xlib)( Display*, Window); -int (*XMapWindow_dylibloader_wrapper_xlib)( Display*, Window); -int (*XMaskEvent_dylibloader_wrapper_xlib)( Display*, long, XEvent*); -int (*XMaxCmapsOfScreen_dylibloader_wrapper_xlib)( Screen*); -int (*XMinCmapsOfScreen_dylibloader_wrapper_xlib)( Screen*); -int (*XMoveResizeWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int); -int (*XMoveWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int); -int (*XNextEvent_dylibloader_wrapper_xlib)( Display*, XEvent*); -int (*XNoOp_dylibloader_wrapper_xlib)( Display*); -int (*XParseColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, XColor*); -int (*XParseGeometry_dylibloader_wrapper_xlib)(const char*, int*, int*, unsigned int*, unsigned int*); -int (*XPeekEvent_dylibloader_wrapper_xlib)( Display*, XEvent*); -int (*XPeekIfEvent_dylibloader_wrapper_xlib)( Display*, XEvent*, Bool (*) (Display*, XEvent*, XPointer), XPointer); -int (*XPending_dylibloader_wrapper_xlib)( Display*); -int (*XPlanesOfScreen_dylibloader_wrapper_xlib)( Screen*); -int (*XProtocolRevision_dylibloader_wrapper_xlib)( Display*); -int (*XProtocolVersion_dylibloader_wrapper_xlib)( Display*); -int (*XPutBackEvent_dylibloader_wrapper_xlib)( Display*, XEvent*); -int (*XPutImage_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int); -int (*XQLength_dylibloader_wrapper_xlib)( Display*); -int (*XQueryBestCursor_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); -int (*XQueryBestSize_dylibloader_wrapper_xlib)( Display*, int, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); -int (*XQueryBestStipple_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); -int (*XQueryBestTile_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); -int (*XQueryColor_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*); -int (*XQueryColors_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*, int); -int (*XQueryExtension_dylibloader_wrapper_xlib)( Display*,const char*, int*, int*, int*); -int (*XQueryKeymap_dylibloader_wrapper_xlib)( Display*, char [32]); -int (*XQueryPointer_dylibloader_wrapper_xlib)( Display*, Window, Window*, Window*, int*, int*, int*, int*, unsigned int*); -int (*XQueryTextExtents_dylibloader_wrapper_xlib)( Display*, XID,const char*, int, int*, int*, int*, XCharStruct*); -int (*XQueryTextExtents16_dylibloader_wrapper_xlib)( Display*, XID,const XChar2b*, int, int*, int*, int*, XCharStruct*); -int (*XQueryTree_dylibloader_wrapper_xlib)( Display*, Window, Window*, Window*, Window**, unsigned int*); -int (*XRaiseWindow_dylibloader_wrapper_xlib)( Display*, Window); -int (*XReadBitmapFile_dylibloader_wrapper_xlib)( Display*, Drawable,const char*, unsigned int*, unsigned int*, Pixmap*, int*, int*); -int (*XReadBitmapFileData_dylibloader_wrapper_xlib)(const char*, unsigned int*, unsigned int*, unsigned char**, int*, int*); -int (*XRebindKeysym_dylibloader_wrapper_xlib)( Display*, KeySym, KeySym*, int,const unsigned char*, int); -int (*XRecolorCursor_dylibloader_wrapper_xlib)( Display*, Cursor, XColor*, XColor*); -int (*XRefreshKeyboardMapping_dylibloader_wrapper_xlib)( XMappingEvent*); -int (*XRemoveFromSaveSet_dylibloader_wrapper_xlib)( Display*, Window); -int (*XRemoveHost_dylibloader_wrapper_xlib)( Display*, XHostAddress*); -int (*XRemoveHosts_dylibloader_wrapper_xlib)( Display*, XHostAddress*, int); -int (*XReparentWindow_dylibloader_wrapper_xlib)( Display*, Window, Window, int, int); -int (*XResetScreenSaver_dylibloader_wrapper_xlib)( Display*); -int (*XResizeWindow_dylibloader_wrapper_xlib)( Display*, Window, unsigned int, unsigned int); -int (*XRestackWindows_dylibloader_wrapper_xlib)( Display*, Window*, int); -int (*XRotateBuffers_dylibloader_wrapper_xlib)( Display*, int); -int (*XRotateWindowProperties_dylibloader_wrapper_xlib)( Display*, Window, Atom*, int, int); -int (*XScreenCount_dylibloader_wrapper_xlib)( Display*); -int (*XSelectInput_dylibloader_wrapper_xlib)( Display*, Window, long); -int (*XSendEvent_dylibloader_wrapper_xlib)( Display*, Window, int, long, XEvent*); -int (*XSetAccessControl_dylibloader_wrapper_xlib)( Display*, int); -int (*XSetArcMode_dylibloader_wrapper_xlib)( Display*, GC, int); -int (*XSetBackground_dylibloader_wrapper_xlib)( Display*, GC, unsigned long); -int (*XSetClipMask_dylibloader_wrapper_xlib)( Display*, GC, Pixmap); -int (*XSetClipOrigin_dylibloader_wrapper_xlib)( Display*, GC, int, int); -int (*XSetClipRectangles_dylibloader_wrapper_xlib)( Display*, GC, int, int, XRectangle*, int, int); -int (*XSetCloseDownMode_dylibloader_wrapper_xlib)( Display*, int); -int (*XSetCommand_dylibloader_wrapper_xlib)( Display*, Window, char**, int); -int (*XSetDashes_dylibloader_wrapper_xlib)( Display*, GC, int,const char*, int); -int (*XSetFillRule_dylibloader_wrapper_xlib)( Display*, GC, int); -int (*XSetFillStyle_dylibloader_wrapper_xlib)( Display*, GC, int); -int (*XSetFont_dylibloader_wrapper_xlib)( Display*, GC, Font); -int (*XSetFontPath_dylibloader_wrapper_xlib)( Display*, char**, int); -int (*XSetForeground_dylibloader_wrapper_xlib)( Display*, GC, unsigned long); -int (*XSetFunction_dylibloader_wrapper_xlib)( Display*, GC, int); -int (*XSetGraphicsExposures_dylibloader_wrapper_xlib)( Display*, GC, int); -int (*XSetIconName_dylibloader_wrapper_xlib)( Display*, Window,const char*); -int (*XSetInputFocus_dylibloader_wrapper_xlib)( Display*, Window, int, Time); -int (*XSetLineAttributes_dylibloader_wrapper_xlib)( Display*, GC, unsigned int, int, int, int); -int (*XSetModifierMapping_dylibloader_wrapper_xlib)( Display*, XModifierKeymap*); -int (*XSetPlaneMask_dylibloader_wrapper_xlib)( Display*, GC, unsigned long); -int (*XSetPointerMapping_dylibloader_wrapper_xlib)( Display*,const unsigned char*, int); -int (*XSetScreenSaver_dylibloader_wrapper_xlib)( Display*, int, int, int, int); -int (*XSetSelectionOwner_dylibloader_wrapper_xlib)( Display*, Atom, Window, Time); -int (*XSetState_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, unsigned long, int, unsigned long); -int (*XSetStipple_dylibloader_wrapper_xlib)( Display*, GC, Pixmap); -int (*XSetSubwindowMode_dylibloader_wrapper_xlib)( Display*, GC, int); -int (*XSetTSOrigin_dylibloader_wrapper_xlib)( Display*, GC, int, int); -int (*XSetTile_dylibloader_wrapper_xlib)( Display*, GC, Pixmap); -int (*XSetWindowBackground_dylibloader_wrapper_xlib)( Display*, Window, unsigned long); -int (*XSetWindowBackgroundPixmap_dylibloader_wrapper_xlib)( Display*, Window, Pixmap); -int (*XSetWindowBorder_dylibloader_wrapper_xlib)( Display*, Window, unsigned long); -int (*XSetWindowBorderPixmap_dylibloader_wrapper_xlib)( Display*, Window, Pixmap); -int (*XSetWindowBorderWidth_dylibloader_wrapper_xlib)( Display*, Window, unsigned int); -int (*XSetWindowColormap_dylibloader_wrapper_xlib)( Display*, Window, Colormap); -int (*XStoreBuffer_dylibloader_wrapper_xlib)( Display*,const char*, int, int); -int (*XStoreBytes_dylibloader_wrapper_xlib)( Display*,const char*, int); -int (*XStoreColor_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*); -int (*XStoreColors_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*, int); -int (*XStoreName_dylibloader_wrapper_xlib)( Display*, Window,const char*); -int (*XStoreNamedColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, unsigned long, int); -int (*XSync_dylibloader_wrapper_xlib)( Display*, int); -int (*XTextExtents_dylibloader_wrapper_xlib)( XFontStruct*,const char*, int, int*, int*, int*, XCharStruct*); -int (*XTextExtents16_dylibloader_wrapper_xlib)( XFontStruct*,const XChar2b*, int, int*, int*, int*, XCharStruct*); -int (*XTextWidth_dylibloader_wrapper_xlib)( XFontStruct*,const char*, int); -int (*XTextWidth16_dylibloader_wrapper_xlib)( XFontStruct*,const XChar2b*, int); -int (*XTranslateCoordinates_dylibloader_wrapper_xlib)( Display*, Window, Window, int, int, int*, int*, Window*); -int (*XUndefineCursor_dylibloader_wrapper_xlib)( Display*, Window); -int (*XUngrabButton_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, Window); -int (*XUngrabKey_dylibloader_wrapper_xlib)( Display*, int, unsigned int, Window); -int (*XUngrabKeyboard_dylibloader_wrapper_xlib)( Display*, Time); -int (*XUngrabPointer_dylibloader_wrapper_xlib)( Display*, Time); -int (*XUngrabServer_dylibloader_wrapper_xlib)( Display*); -int (*XUninstallColormap_dylibloader_wrapper_xlib)( Display*, Colormap); -int (*XUnloadFont_dylibloader_wrapper_xlib)( Display*, Font); -int (*XUnmapSubwindows_dylibloader_wrapper_xlib)( Display*, Window); -int (*XUnmapWindow_dylibloader_wrapper_xlib)( Display*, Window); -int (*XVendorRelease_dylibloader_wrapper_xlib)( Display*); -int (*XWarpPointer_dylibloader_wrapper_xlib)( Display*, Window, Window, int, int, unsigned int, unsigned int, int, int); -int (*XWidthMMOfScreen_dylibloader_wrapper_xlib)( Screen*); -int (*XWidthOfScreen_dylibloader_wrapper_xlib)( Screen*); -int (*XWindowEvent_dylibloader_wrapper_xlib)( Display*, Window, long, XEvent*); -int (*XWriteBitmapFile_dylibloader_wrapper_xlib)( Display*,const char*, Pixmap, unsigned int, unsigned int, int, int); -int (*XSupportsLocale_dylibloader_wrapper_xlib)( void); -char* (*XSetLocaleModifiers_dylibloader_wrapper_xlib)(const char*); -XOM (*XOpenOM_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*,const char*,const char*); -int (*XCloseOM_dylibloader_wrapper_xlib)( XOM); -char* (*XSetOMValues_dylibloader_wrapper_xlib)( XOM,...); -char* (*XGetOMValues_dylibloader_wrapper_xlib)( XOM,...); -Display* (*XDisplayOfOM_dylibloader_wrapper_xlib)( XOM); -char* (*XLocaleOfOM_dylibloader_wrapper_xlib)( XOM); -XOC (*XCreateOC_dylibloader_wrapper_xlib)( XOM,...); -void (*XDestroyOC_dylibloader_wrapper_xlib)( XOC); -XOM (*XOMOfOC_dylibloader_wrapper_xlib)( XOC); -char* (*XSetOCValues_dylibloader_wrapper_xlib)( XOC,...); -char* (*XGetOCValues_dylibloader_wrapper_xlib)( XOC,...); -XFontSet (*XCreateFontSet_dylibloader_wrapper_xlib)( Display*,const char*, char***, int*, char**); -void (*XFreeFontSet_dylibloader_wrapper_xlib)( Display*, XFontSet); -int (*XFontsOfFontSet_dylibloader_wrapper_xlib)( XFontSet, XFontStruct***, char***); -char* (*XBaseFontNameListOfFontSet_dylibloader_wrapper_xlib)( XFontSet); -char* (*XLocaleOfFontSet_dylibloader_wrapper_xlib)( XFontSet); -int (*XContextDependentDrawing_dylibloader_wrapper_xlib)( XFontSet); -int (*XDirectionalDependentDrawing_dylibloader_wrapper_xlib)( XFontSet); -int (*XContextualDrawing_dylibloader_wrapper_xlib)( XFontSet); -XFontSetExtents* (*XExtentsOfFontSet_dylibloader_wrapper_xlib)( XFontSet); -int (*XmbTextEscapement_dylibloader_wrapper_xlib)( XFontSet,const char*, int); -int (*XwcTextEscapement_dylibloader_wrapper_xlib)( XFontSet,const wchar_t*, int); -int (*Xutf8TextEscapement_dylibloader_wrapper_xlib)( XFontSet,const char*, int); -int (*XmbTextExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*); -int (*XwcTextExtents_dylibloader_wrapper_xlib)( XFontSet,const wchar_t*, int, XRectangle*, XRectangle*); -int (*Xutf8TextExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*); -int (*XmbTextPerCharExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*, int, int*, XRectangle*, XRectangle*); -int (*XwcTextPerCharExtents_dylibloader_wrapper_xlib)( XFontSet,const wchar_t*, int, XRectangle*, XRectangle*, int, int*, XRectangle*, XRectangle*); -int (*Xutf8TextPerCharExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*, int, int*, XRectangle*, XRectangle*); -void (*XmbDrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XmbTextItem*, int); -void (*XwcDrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XwcTextItem*, int); -void (*Xutf8DrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XmbTextItem*, int); -void (*XmbDrawString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); -void (*XwcDrawString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const wchar_t*, int); -void (*Xutf8DrawString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); -void (*XmbDrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); -void (*XwcDrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const wchar_t*, int); -void (*Xutf8DrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); -XIM (*XOpenIM_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*, char*, char*); -int (*XCloseIM_dylibloader_wrapper_xlib)( XIM); -char* (*XGetIMValues_dylibloader_wrapper_xlib)( XIM,...); -char* (*XSetIMValues_dylibloader_wrapper_xlib)( XIM,...); -Display* (*XDisplayOfIM_dylibloader_wrapper_xlib)( XIM); -char* (*XLocaleOfIM_dylibloader_wrapper_xlib)( XIM); -XIC (*XCreateIC_dylibloader_wrapper_xlib)( XIM,...); -void (*XDestroyIC_dylibloader_wrapper_xlib)( XIC); -void (*XSetICFocus_dylibloader_wrapper_xlib)( XIC); -void (*XUnsetICFocus_dylibloader_wrapper_xlib)( XIC); -wchar_t* (*XwcResetIC_dylibloader_wrapper_xlib)( XIC); -char* (*XmbResetIC_dylibloader_wrapper_xlib)( XIC); -char* (*Xutf8ResetIC_dylibloader_wrapper_xlib)( XIC); -char* (*XSetICValues_dylibloader_wrapper_xlib)( XIC,...); -char* (*XGetICValues_dylibloader_wrapper_xlib)( XIC,...); -XIM (*XIMOfIC_dylibloader_wrapper_xlib)( XIC); -int (*XFilterEvent_dylibloader_wrapper_xlib)( XEvent*, Window); -int (*XmbLookupString_dylibloader_wrapper_xlib)( XIC, XKeyPressedEvent*, char*, int, KeySym*, int*); -int (*XwcLookupString_dylibloader_wrapper_xlib)( XIC, XKeyPressedEvent*, wchar_t*, int, KeySym*, int*); -int (*Xutf8LookupString_dylibloader_wrapper_xlib)( XIC, XKeyPressedEvent*, char*, int, KeySym*, int*); -XVaNestedList (*XVaCreateNestedList_dylibloader_wrapper_xlib)( int,...); -int (*XRegisterIMInstantiateCallback_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*, char*, char*, XIDProc, XPointer); -int (*XUnregisterIMInstantiateCallback_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*, char*, char*, XIDProc, XPointer); -int (*XInternalConnectionNumbers_dylibloader_wrapper_xlib)( Display*, int**, int*); -void (*XProcessInternalConnection_dylibloader_wrapper_xlib)( Display*, int); -int (*XAddConnectionWatch_dylibloader_wrapper_xlib)( Display*, XConnectionWatchProc, XPointer); -void (*XRemoveConnectionWatch_dylibloader_wrapper_xlib)( Display*, XConnectionWatchProc, XPointer); -void (*XSetAuthorization_dylibloader_wrapper_xlib)( char*, int, char*, int); -int (*_Xmbtowc_dylibloader_wrapper_xlib)( wchar_t*, char*, int); -int (*_Xwctomb_dylibloader_wrapper_xlib)( char*, wchar_t); -int (*XGetEventData_dylibloader_wrapper_xlib)( Display*, XGenericEventCookie*); -void (*XFreeEventData_dylibloader_wrapper_xlib)( Display*, XGenericEventCookie*); -XClassHint* (*XAllocClassHint_dylibloader_wrapper_xlib)( void); -XIconSize* (*XAllocIconSize_dylibloader_wrapper_xlib)( void); -XSizeHints* (*XAllocSizeHints_dylibloader_wrapper_xlib)( void); -XStandardColormap* (*XAllocStandardColormap_dylibloader_wrapper_xlib)( void); -XWMHints* (*XAllocWMHints_dylibloader_wrapper_xlib)( void); -int (*XClipBox_dylibloader_wrapper_xlib)( Region, XRectangle*); -Region (*XCreateRegion_dylibloader_wrapper_xlib)( void); -const char* (*XDefaultString_dylibloader_wrapper_xlib)( void); -int (*XDeleteContext_dylibloader_wrapper_xlib)( Display*, XID, XContext); -int (*XDestroyRegion_dylibloader_wrapper_xlib)( Region); -int (*XEmptyRegion_dylibloader_wrapper_xlib)( Region); -int (*XEqualRegion_dylibloader_wrapper_xlib)( Region, Region); -int (*XFindContext_dylibloader_wrapper_xlib)( Display*, XID, XContext, XPointer*); -int (*XGetClassHint_dylibloader_wrapper_xlib)( Display*, Window, XClassHint*); -int (*XGetIconSizes_dylibloader_wrapper_xlib)( Display*, Window, XIconSize**, int*); -int (*XGetNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); -int (*XGetRGBColormaps_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap**, int*, Atom); -int (*XGetSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, Atom); -int (*XGetStandardColormap_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap*, Atom); -int (*XGetTextProperty_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*, Atom); -XVisualInfo* (*XGetVisualInfo_dylibloader_wrapper_xlib)( Display*, long, XVisualInfo*, int*); -int (*XGetWMClientMachine_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); -XWMHints* (*XGetWMHints_dylibloader_wrapper_xlib)( Display*, Window); -int (*XGetWMIconName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); -int (*XGetWMName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); -int (*XGetWMNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, long*); -int (*XGetWMSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, long*, Atom); -int (*XGetZoomHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); -int (*XIntersectRegion_dylibloader_wrapper_xlib)( Region, Region, Region); -void (*XConvertCase_dylibloader_wrapper_xlib)( KeySym, KeySym*, KeySym*); -int (*XLookupString_dylibloader_wrapper_xlib)( XKeyEvent*, char*, int, KeySym*, XComposeStatus*); -int (*XMatchVisualInfo_dylibloader_wrapper_xlib)( Display*, int, int, int, XVisualInfo*); -int (*XOffsetRegion_dylibloader_wrapper_xlib)( Region, int, int); -int (*XPointInRegion_dylibloader_wrapper_xlib)( Region, int, int); -Region (*XPolygonRegion_dylibloader_wrapper_xlib)( XPoint*, int, int); -int (*XRectInRegion_dylibloader_wrapper_xlib)( Region, int, int, unsigned int, unsigned int); -int (*XSaveContext_dylibloader_wrapper_xlib)( Display*, XID, XContext,const char*); -int (*XSetClassHint_dylibloader_wrapper_xlib)( Display*, Window, XClassHint*); -int (*XSetIconSizes_dylibloader_wrapper_xlib)( Display*, Window, XIconSize*, int); -int (*XSetNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); -void (*XSetRGBColormaps_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap*, int, Atom); -int (*XSetSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, Atom); -int (*XSetStandardProperties_dylibloader_wrapper_xlib)( Display*, Window,const char*,const char*, Pixmap, char**, int, XSizeHints*); -void (*XSetTextProperty_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*, Atom); -void (*XSetWMClientMachine_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); -int (*XSetWMHints_dylibloader_wrapper_xlib)( Display*, Window, XWMHints*); -void (*XSetWMIconName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); -void (*XSetWMName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); -void (*XSetWMNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); -void (*XSetWMProperties_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*, XTextProperty*, char**, int, XSizeHints*, XWMHints*, XClassHint*); -void (*XmbSetWMProperties_dylibloader_wrapper_xlib)( Display*, Window,const char*,const char*, char**, int, XSizeHints*, XWMHints*, XClassHint*); -void (*Xutf8SetWMProperties_dylibloader_wrapper_xlib)( Display*, Window,const char*,const char*, char**, int, XSizeHints*, XWMHints*, XClassHint*); -void (*XSetWMSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, Atom); -int (*XSetRegion_dylibloader_wrapper_xlib)( Display*, GC, Region); -void (*XSetStandardColormap_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap*, Atom); -int (*XSetZoomHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); -int (*XShrinkRegion_dylibloader_wrapper_xlib)( Region, int, int); -int (*XStringListToTextProperty_dylibloader_wrapper_xlib)( char**, int, XTextProperty*); -int (*XSubtractRegion_dylibloader_wrapper_xlib)( Region, Region, Region); -int (*XmbTextListToTextProperty_dylibloader_wrapper_xlib)( Display*, char**, int, XICCEncodingStyle, XTextProperty*); -int (*XwcTextListToTextProperty_dylibloader_wrapper_xlib)( Display*, wchar_t**, int, XICCEncodingStyle, XTextProperty*); -int (*Xutf8TextListToTextProperty_dylibloader_wrapper_xlib)( Display*, char**, int, XICCEncodingStyle, XTextProperty*); -void (*XwcFreeStringList_dylibloader_wrapper_xlib)( wchar_t**); -int (*XTextPropertyToStringList_dylibloader_wrapper_xlib)( XTextProperty*, char***, int*); -int (*XmbTextPropertyToTextList_dylibloader_wrapper_xlib)( Display*,const XTextProperty*, char***, int*); -int (*XwcTextPropertyToTextList_dylibloader_wrapper_xlib)( Display*,const XTextProperty*, wchar_t***, int*); -int (*Xutf8TextPropertyToTextList_dylibloader_wrapper_xlib)( Display*,const XTextProperty*, char***, int*); -int (*XUnionRectWithRegion_dylibloader_wrapper_xlib)( XRectangle*, Region, Region); -int (*XUnionRegion_dylibloader_wrapper_xlib)( Region, Region, Region); -int (*XWMGeometry_dylibloader_wrapper_xlib)( Display*, int,const char*,const char*, unsigned int, XSizeHints*, int*, int*, int*, int*, int*); -int (*XXorRegion_dylibloader_wrapper_xlib)( Region, Region, Region); -int (*XkbIgnoreExtension_dylibloader_wrapper_xlib)( int); -Display* (*XkbOpenDisplay_dylibloader_wrapper_xlib)( char*, int*, int*, int*, int*, int*); -int (*XkbQueryExtension_dylibloader_wrapper_xlib)( Display*, int*, int*, int*, int*, int*); -int (*XkbUseExtension_dylibloader_wrapper_xlib)( Display*, int*, int*); -int (*XkbLibraryVersion_dylibloader_wrapper_xlib)( int*, int*); -unsigned int (*XkbSetXlibControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); -unsigned int (*XkbGetXlibControls_dylibloader_wrapper_xlib)( Display*); -unsigned int (*XkbXlibControlsImplemented_dylibloader_wrapper_xlib)( void); -void (*XkbSetAtomFuncs_dylibloader_wrapper_xlib)( XkbInternAtomFunc, XkbGetAtomNameFunc); -KeySym (*XkbKeycodeToKeysym_dylibloader_wrapper_xlib)( Display*, KeyCode, int, int); -unsigned int (*XkbKeysymToModifiers_dylibloader_wrapper_xlib)( Display*, KeySym); -int (*XkbLookupKeySym_dylibloader_wrapper_xlib)( Display*, KeyCode, unsigned int, unsigned int*, KeySym*); -int (*XkbLookupKeyBinding_dylibloader_wrapper_xlib)( Display*, KeySym, unsigned int, char*, int, int*); -int (*XkbTranslateKeyCode_dylibloader_wrapper_xlib)( XkbDescPtr, KeyCode, unsigned int, unsigned int*, KeySym*); -int (*XkbTranslateKeySym_dylibloader_wrapper_xlib)( Display*, KeySym*, unsigned int, char*, int, int*); -int (*XkbSetAutoRepeatRate_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); -int (*XkbGetAutoRepeatRate_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*, unsigned int*); -int (*XkbChangeEnabledControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); -int (*XkbDeviceBell_dylibloader_wrapper_xlib)( Display*, Window, int, int, int, int, Atom); -int (*XkbForceDeviceBell_dylibloader_wrapper_xlib)( Display*, int, int, int, int); -int (*XkbDeviceBellEvent_dylibloader_wrapper_xlib)( Display*, Window, int, int, int, int, Atom); -int (*XkbBell_dylibloader_wrapper_xlib)( Display*, Window, int, Atom); -int (*XkbForceBell_dylibloader_wrapper_xlib)( Display*, int); -int (*XkbBellEvent_dylibloader_wrapper_xlib)( Display*, Window, int, Atom); -int (*XkbSelectEvents_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); -int (*XkbSelectEventDetails_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned long, unsigned long); -void (*XkbNoteMapChanges_dylibloader_wrapper_xlib)( XkbMapChangesPtr, XkbMapNotifyEvent*, unsigned int); -void (*XkbNoteNameChanges_dylibloader_wrapper_xlib)( XkbNameChangesPtr, XkbNamesNotifyEvent*, unsigned int); -int (*XkbGetIndicatorState_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*); -int (*XkbGetIndicatorMap_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); -int (*XkbSetIndicatorMap_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); -int (*XkbGetNamedIndicator_dylibloader_wrapper_xlib)( Display*, Atom, int*, int*, XkbIndicatorMapPtr, int*); -int (*XkbGetNamedDeviceIndicator_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, Atom, int*, int*, XkbIndicatorMapPtr, int*); -int (*XkbSetNamedIndicator_dylibloader_wrapper_xlib)( Display*, Atom, int, int, int, XkbIndicatorMapPtr); -int (*XkbSetNamedDeviceIndicator_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, Atom, int, int, int, XkbIndicatorMapPtr); -int (*XkbLockModifiers_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); -int (*XkbLatchModifiers_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); -int (*XkbLockGroup_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); -int (*XkbLatchGroup_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); -int (*XkbSetServerInternalMods_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); -int (*XkbSetIgnoreLockMods_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); -int (*XkbVirtualModsToReal_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int*); -int (*XkbComputeEffectiveMap_dylibloader_wrapper_xlib)( XkbDescPtr, XkbKeyTypePtr, unsigned char*); -int (*XkbInitCanonicalKeyTypes_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); -XkbDescPtr (*XkbAllocKeyboard_dylibloader_wrapper_xlib)( void); -void (*XkbFreeKeyboard_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); -int (*XkbAllocClientMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int); -int (*XkbAllocServerMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int); -void (*XkbFreeClientMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); -void (*XkbFreeServerMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); -XkbKeyTypePtr (*XkbAddKeyType_dylibloader_wrapper_xlib)( XkbDescPtr, Atom, int, int, int); -int (*XkbAllocIndicatorMaps_dylibloader_wrapper_xlib)( XkbDescPtr); -void (*XkbFreeIndicatorMaps_dylibloader_wrapper_xlib)( XkbDescPtr); -XkbDescPtr (*XkbGetMap_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); -int (*XkbGetUpdatedMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); -int (*XkbGetMapChanges_dylibloader_wrapper_xlib)( Display*, XkbDescPtr, XkbMapChangesPtr); -int (*XkbRefreshKeyboardMapping_dylibloader_wrapper_xlib)( XkbMapNotifyEvent*); -int (*XkbGetKeyTypes_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); -int (*XkbGetKeySyms_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); -int (*XkbGetKeyActions_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); -int (*XkbGetKeyBehaviors_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); -int (*XkbGetVirtualMods_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); -int (*XkbGetKeyExplicitComponents_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); -int (*XkbGetKeyModifierMap_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); -int (*XkbGetKeyVirtualModMap_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); -int (*XkbAllocControls_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int); -void (*XkbFreeControls_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); -int (*XkbGetControls_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); -int (*XkbSetControls_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); -void (*XkbNoteControlsChanges_dylibloader_wrapper_xlib)( XkbControlsChangesPtr, XkbControlsNotifyEvent*, unsigned int); -int (*XkbAllocCompatMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int); -void (*XkbFreeCompatMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); -int (*XkbGetCompatMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); -int (*XkbSetCompatMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr, int); -int (*XkbAllocNames_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int, int); -int (*XkbGetNames_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); -int (*XkbSetNames_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, XkbDescPtr); -int (*XkbChangeNames_dylibloader_wrapper_xlib)( Display*, XkbDescPtr, XkbNameChangesPtr); -void (*XkbFreeNames_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); -int (*XkbGetState_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbStatePtr); -int (*XkbSetMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); -int (*XkbChangeMap_dylibloader_wrapper_xlib)( Display*, XkbDescPtr, XkbMapChangesPtr); -int (*XkbSetDetectableAutoRepeat_dylibloader_wrapper_xlib)( Display*, int, int*); -int (*XkbGetDetectableAutoRepeat_dylibloader_wrapper_xlib)( Display*, int*); -int (*XkbSetAutoResetControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*, unsigned int*); -int (*XkbGetAutoResetControls_dylibloader_wrapper_xlib)( Display*, unsigned int*, unsigned int*); -int (*XkbSetPerClientControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*); -int (*XkbGetPerClientControls_dylibloader_wrapper_xlib)( Display*, unsigned int*); -int (*XkbCopyKeyType_dylibloader_wrapper_xlib)( XkbKeyTypePtr, XkbKeyTypePtr); -int (*XkbCopyKeyTypes_dylibloader_wrapper_xlib)( XkbKeyTypePtr, XkbKeyTypePtr, int); -int (*XkbResizeKeyType_dylibloader_wrapper_xlib)( XkbDescPtr, int, int, int, int); -KeySym* (*XkbResizeKeySyms_dylibloader_wrapper_xlib)( XkbDescPtr, int, int); -XkbAction* (*XkbResizeKeyActions_dylibloader_wrapper_xlib)( XkbDescPtr, int, int); -int (*XkbChangeTypesOfKey_dylibloader_wrapper_xlib)( XkbDescPtr, int, int, unsigned int, int*, XkbMapChangesPtr); -int (*XkbChangeKeycodeRange_dylibloader_wrapper_xlib)( XkbDescPtr, int, int, XkbChangesPtr); -XkbComponentListPtr (*XkbListComponents_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbComponentNamesPtr, int*); -void (*XkbFreeComponentList_dylibloader_wrapper_xlib)( XkbComponentListPtr); -XkbDescPtr (*XkbGetKeyboard_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); -XkbDescPtr (*XkbGetKeyboardByName_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbComponentNamesPtr, unsigned int, unsigned int, int); -int (*XkbKeyTypesForCoreSymbols_dylibloader_wrapper_xlib)( XkbDescPtr, int, KeySym*, unsigned int, int*, KeySym*); -int (*XkbApplyCompatMapToKey_dylibloader_wrapper_xlib)( XkbDescPtr, KeyCode, XkbChangesPtr); -int (*XkbUpdateMapFromCore_dylibloader_wrapper_xlib)( XkbDescPtr, KeyCode, int, int, KeySym*, XkbChangesPtr); -XkbDeviceLedInfoPtr (*XkbAddDeviceLedInfo_dylibloader_wrapper_xlib)( XkbDeviceInfoPtr, unsigned int, unsigned int); -int (*XkbResizeDeviceButtonActions_dylibloader_wrapper_xlib)( XkbDeviceInfoPtr, unsigned int); -XkbDeviceInfoPtr (*XkbAllocDeviceInfo_dylibloader_wrapper_xlib)( unsigned int, unsigned int, unsigned int); -void (*XkbFreeDeviceInfo_dylibloader_wrapper_xlib)( XkbDeviceInfoPtr, unsigned int, int); -void (*XkbNoteDeviceChanges_dylibloader_wrapper_xlib)( XkbDeviceChangesPtr, XkbExtensionDeviceNotifyEvent*, unsigned int); -XkbDeviceInfoPtr (*XkbGetDeviceInfo_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, unsigned int); -int (*XkbGetDeviceInfoChanges_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, XkbDeviceChangesPtr); -int (*XkbGetDeviceButtonActions_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, int, unsigned int, unsigned int); -int (*XkbGetDeviceLedInfo_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, unsigned int, unsigned int, unsigned int); -int (*XkbSetDeviceInfo_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDeviceInfoPtr); -int (*XkbChangeDeviceInfo_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, XkbDeviceChangesPtr); -int (*XkbSetDeviceLedInfo_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, unsigned int, unsigned int, unsigned int); -int (*XkbSetDeviceButtonActions_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, unsigned int, unsigned int); -char (*XkbToControl_dylibloader_wrapper_xlib)( char); -int (*XkbSetDebuggingFlags_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, char*, unsigned int, unsigned int, unsigned int*, unsigned int*); -int (*XkbApplyVirtualModChanges_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, XkbChangesPtr); -int (*XkbUpdateActionVirtualMods_dylibloader_wrapper_xlib)( XkbDescPtr, XkbAction*, unsigned int); -void (*XkbUpdateKeyTypeVirtualMods_dylibloader_wrapper_xlib)( XkbDescPtr, XkbKeyTypePtr, unsigned int, XkbChangesPtr); +int (*_Xmblen_dylibloader_wrapper_xlib)(char *, int); +XFontStruct *(*XLoadQueryFont_dylibloader_wrapper_xlib)(Display *, const char *); +XFontStruct *(*XQueryFont_dylibloader_wrapper_xlib)(Display *, XID); +XTimeCoord *(*XGetMotionEvents_dylibloader_wrapper_xlib)(Display *, Window, Time, Time, int *); +XModifierKeymap *(*XDeleteModifiermapEntry_dylibloader_wrapper_xlib)(XModifierKeymap *, KeyCode, int); +XModifierKeymap *(*XGetModifierMapping_dylibloader_wrapper_xlib)(Display *); +XModifierKeymap *(*XInsertModifiermapEntry_dylibloader_wrapper_xlib)(XModifierKeymap *, KeyCode, int); +XModifierKeymap *(*XNewModifiermap_dylibloader_wrapper_xlib)(int); +XImage *(*XCreateImage_dylibloader_wrapper_xlib)(Display *, Visual *, unsigned int, int, int, char *, unsigned int, unsigned int, int, int); +int (*XInitImage_dylibloader_wrapper_xlib)(XImage *); +XImage *(*XGetImage_dylibloader_wrapper_xlib)(Display *, Drawable, int, int, unsigned int, unsigned int, unsigned long, int); +XImage *(*XGetSubImage_dylibloader_wrapper_xlib)(Display *, Drawable, int, int, unsigned int, unsigned int, unsigned long, int, XImage *, int, int); +Display *(*XOpenDisplay_dylibloader_wrapper_xlib)(const char *); +void (*XrmInitialize_dylibloader_wrapper_xlib)(void); +char *(*XFetchBytes_dylibloader_wrapper_xlib)(Display *, int *); +char *(*XFetchBuffer_dylibloader_wrapper_xlib)(Display *, int *, int); +char *(*XGetAtomName_dylibloader_wrapper_xlib)(Display *, Atom); +int (*XGetAtomNames_dylibloader_wrapper_xlib)(Display *, Atom *, int, char **); +char *(*XGetDefault_dylibloader_wrapper_xlib)(Display *, const char *, const char *); +char *(*XDisplayName_dylibloader_wrapper_xlib)(const char *); +char *(*XKeysymToString_dylibloader_wrapper_xlib)(KeySym); +int (*(*XSynchronize_dylibloader_wrapper_xlib)(Display *, int))(Display *); +int (*(*XSetAfterFunction_dylibloader_wrapper_xlib)(Display *, int (*)(Display *)))(Display *); +Atom (*XInternAtom_dylibloader_wrapper_xlib)(Display *, const char *, int); +int (*XInternAtoms_dylibloader_wrapper_xlib)(Display *, char **, int, int, Atom *); +Colormap (*XCopyColormapAndFree_dylibloader_wrapper_xlib)(Display *, Colormap); +Colormap (*XCreateColormap_dylibloader_wrapper_xlib)(Display *, Window, Visual *, int); +Cursor (*XCreatePixmapCursor_dylibloader_wrapper_xlib)(Display *, Pixmap, Pixmap, XColor *, XColor *, unsigned int, unsigned int); +Cursor (*XCreateGlyphCursor_dylibloader_wrapper_xlib)(Display *, Font, Font, unsigned int, unsigned int, const XColor *, const XColor *); +Cursor (*XCreateFontCursor_dylibloader_wrapper_xlib)(Display *, unsigned int); +Font (*XLoadFont_dylibloader_wrapper_xlib)(Display *, const char *); +GC (*XCreateGC_dylibloader_wrapper_xlib)(Display *, Drawable, unsigned long, XGCValues *); +GContext (*XGContextFromGC_dylibloader_wrapper_xlib)(GC); +void (*XFlushGC_dylibloader_wrapper_xlib)(Display *, GC); +Pixmap (*XCreatePixmap_dylibloader_wrapper_xlib)(Display *, Drawable, unsigned int, unsigned int, unsigned int); +Pixmap (*XCreateBitmapFromData_dylibloader_wrapper_xlib)(Display *, Drawable, const char *, unsigned int, unsigned int); +Pixmap (*XCreatePixmapFromBitmapData_dylibloader_wrapper_xlib)(Display *, Drawable, char *, unsigned int, unsigned int, unsigned long, unsigned long, unsigned int); +Window (*XCreateSimpleWindow_dylibloader_wrapper_xlib)(Display *, Window, int, int, unsigned int, unsigned int, unsigned int, unsigned long, unsigned long); +Window (*XGetSelectionOwner_dylibloader_wrapper_xlib)(Display *, Atom); +Window (*XCreateWindow_dylibloader_wrapper_xlib)(Display *, Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual *, unsigned long, XSetWindowAttributes *); +Colormap *(*XListInstalledColormaps_dylibloader_wrapper_xlib)(Display *, Window, int *); +char **(*XListFonts_dylibloader_wrapper_xlib)(Display *, const char *, int, int *); +char **(*XListFontsWithInfo_dylibloader_wrapper_xlib)(Display *, const char *, int, int *, XFontStruct **); +char **(*XGetFontPath_dylibloader_wrapper_xlib)(Display *, int *); +char **(*XListExtensions_dylibloader_wrapper_xlib)(Display *, int *); +Atom *(*XListProperties_dylibloader_wrapper_xlib)(Display *, Window, int *); +XHostAddress *(*XListHosts_dylibloader_wrapper_xlib)(Display *, int *, int *); +KeySym (*XKeycodeToKeysym_dylibloader_wrapper_xlib)(Display *, KeyCode, int); +KeySym (*XLookupKeysym_dylibloader_wrapper_xlib)(XKeyEvent *, int); +KeySym *(*XGetKeyboardMapping_dylibloader_wrapper_xlib)(Display *, KeyCode, int, int *); +KeySym (*XStringToKeysym_dylibloader_wrapper_xlib)(const char *); +long (*XMaxRequestSize_dylibloader_wrapper_xlib)(Display *); +long (*XExtendedMaxRequestSize_dylibloader_wrapper_xlib)(Display *); +char *(*XResourceManagerString_dylibloader_wrapper_xlib)(Display *); +char *(*XScreenResourceString_dylibloader_wrapper_xlib)(Screen *); +unsigned long (*XDisplayMotionBufferSize_dylibloader_wrapper_xlib)(Display *); +VisualID (*XVisualIDFromVisual_dylibloader_wrapper_xlib)(Visual *); +int (*XInitThreads_dylibloader_wrapper_xlib)(void); +void (*XLockDisplay_dylibloader_wrapper_xlib)(Display *); +void (*XUnlockDisplay_dylibloader_wrapper_xlib)(Display *); +XExtCodes *(*XInitExtension_dylibloader_wrapper_xlib)(Display *, const char *); +XExtCodes *(*XAddExtension_dylibloader_wrapper_xlib)(Display *); +XExtData *(*XFindOnExtensionList_dylibloader_wrapper_xlib)(XExtData **, int); +XExtData **(*XEHeadOfExtensionList_dylibloader_wrapper_xlib)(XEDataObject); +Window (*XRootWindow_dylibloader_wrapper_xlib)(Display *, int); +Window (*XDefaultRootWindow_dylibloader_wrapper_xlib)(Display *); +Window (*XRootWindowOfScreen_dylibloader_wrapper_xlib)(Screen *); +Visual *(*XDefaultVisual_dylibloader_wrapper_xlib)(Display *, int); +Visual *(*XDefaultVisualOfScreen_dylibloader_wrapper_xlib)(Screen *); +GC (*XDefaultGC_dylibloader_wrapper_xlib)(Display *, int); +GC (*XDefaultGCOfScreen_dylibloader_wrapper_xlib)(Screen *); +unsigned long (*XBlackPixel_dylibloader_wrapper_xlib)(Display *, int); +unsigned long (*XWhitePixel_dylibloader_wrapper_xlib)(Display *, int); +unsigned long (*XAllPlanes_dylibloader_wrapper_xlib)(void); +unsigned long (*XBlackPixelOfScreen_dylibloader_wrapper_xlib)(Screen *); +unsigned long (*XWhitePixelOfScreen_dylibloader_wrapper_xlib)(Screen *); +unsigned long (*XNextRequest_dylibloader_wrapper_xlib)(Display *); +unsigned long (*XLastKnownRequestProcessed_dylibloader_wrapper_xlib)(Display *); +char *(*XServerVendor_dylibloader_wrapper_xlib)(Display *); +char *(*XDisplayString_dylibloader_wrapper_xlib)(Display *); +Colormap (*XDefaultColormap_dylibloader_wrapper_xlib)(Display *, int); +Colormap (*XDefaultColormapOfScreen_dylibloader_wrapper_xlib)(Screen *); +Display *(*XDisplayOfScreen_dylibloader_wrapper_xlib)(Screen *); +Screen *(*XScreenOfDisplay_dylibloader_wrapper_xlib)(Display *, int); +Screen *(*XDefaultScreenOfDisplay_dylibloader_wrapper_xlib)(Display *); +long (*XEventMaskOfScreen_dylibloader_wrapper_xlib)(Screen *); +int (*XScreenNumberOfScreen_dylibloader_wrapper_xlib)(Screen *); +XErrorHandler (*XSetErrorHandler_dylibloader_wrapper_xlib)(XErrorHandler); +XIOErrorHandler (*XSetIOErrorHandler_dylibloader_wrapper_xlib)(XIOErrorHandler); +void (*XSetIOErrorExitHandler_dylibloader_wrapper_xlib)(Display *, XIOErrorExitHandler, void *); +XPixmapFormatValues *(*XListPixmapFormats_dylibloader_wrapper_xlib)(Display *, int *); +int *(*XListDepths_dylibloader_wrapper_xlib)(Display *, int, int *); +int (*XReconfigureWMWindow_dylibloader_wrapper_xlib)(Display *, Window, int, unsigned int, XWindowChanges *); +int (*XGetWMProtocols_dylibloader_wrapper_xlib)(Display *, Window, Atom **, int *); +int (*XSetWMProtocols_dylibloader_wrapper_xlib)(Display *, Window, Atom *, int); +int (*XIconifyWindow_dylibloader_wrapper_xlib)(Display *, Window, int); +int (*XWithdrawWindow_dylibloader_wrapper_xlib)(Display *, Window, int); +int (*XGetCommand_dylibloader_wrapper_xlib)(Display *, Window, char ***, int *); +int (*XGetWMColormapWindows_dylibloader_wrapper_xlib)(Display *, Window, Window **, int *); +int (*XSetWMColormapWindows_dylibloader_wrapper_xlib)(Display *, Window, Window *, int); +void (*XFreeStringList_dylibloader_wrapper_xlib)(char **); +int (*XSetTransientForHint_dylibloader_wrapper_xlib)(Display *, Window, Window); +int (*XActivateScreenSaver_dylibloader_wrapper_xlib)(Display *); +int (*XAddHost_dylibloader_wrapper_xlib)(Display *, XHostAddress *); +int (*XAddHosts_dylibloader_wrapper_xlib)(Display *, XHostAddress *, int); +int (*XAddToExtensionList_dylibloader_wrapper_xlib)(struct _XExtData **, XExtData *); +int (*XAddToSaveSet_dylibloader_wrapper_xlib)(Display *, Window); +int (*XAllocColor_dylibloader_wrapper_xlib)(Display *, Colormap, XColor *); +int (*XAllocColorCells_dylibloader_wrapper_xlib)(Display *, Colormap, int, unsigned long *, unsigned int, unsigned long *, unsigned int); +int (*XAllocColorPlanes_dylibloader_wrapper_xlib)(Display *, Colormap, int, unsigned long *, int, int, int, int, unsigned long *, unsigned long *, unsigned long *); +int (*XAllocNamedColor_dylibloader_wrapper_xlib)(Display *, Colormap, const char *, XColor *, XColor *); +int (*XAllowEvents_dylibloader_wrapper_xlib)(Display *, int, Time); +int (*XAutoRepeatOff_dylibloader_wrapper_xlib)(Display *); +int (*XAutoRepeatOn_dylibloader_wrapper_xlib)(Display *); +int (*XBell_dylibloader_wrapper_xlib)(Display *, int); +int (*XBitmapBitOrder_dylibloader_wrapper_xlib)(Display *); +int (*XBitmapPad_dylibloader_wrapper_xlib)(Display *); +int (*XBitmapUnit_dylibloader_wrapper_xlib)(Display *); +int (*XCellsOfScreen_dylibloader_wrapper_xlib)(Screen *); +int (*XChangeActivePointerGrab_dylibloader_wrapper_xlib)(Display *, unsigned int, Cursor, Time); +int (*XChangeGC_dylibloader_wrapper_xlib)(Display *, GC, unsigned long, XGCValues *); +int (*XChangeKeyboardControl_dylibloader_wrapper_xlib)(Display *, unsigned long, XKeyboardControl *); +int (*XChangeKeyboardMapping_dylibloader_wrapper_xlib)(Display *, int, int, KeySym *, int); +int (*XChangePointerControl_dylibloader_wrapper_xlib)(Display *, int, int, int, int, int); +int (*XChangeProperty_dylibloader_wrapper_xlib)(Display *, Window, Atom, Atom, int, int, const unsigned char *, int); +int (*XChangeSaveSet_dylibloader_wrapper_xlib)(Display *, Window, int); +int (*XChangeWindowAttributes_dylibloader_wrapper_xlib)(Display *, Window, unsigned long, XSetWindowAttributes *); +int (*XCheckIfEvent_dylibloader_wrapper_xlib)(Display *, XEvent *, int (*)(Display *, XEvent *, XPointer), XPointer); +int (*XCheckMaskEvent_dylibloader_wrapper_xlib)(Display *, long, XEvent *); +int (*XCheckTypedEvent_dylibloader_wrapper_xlib)(Display *, int, XEvent *); +int (*XCheckTypedWindowEvent_dylibloader_wrapper_xlib)(Display *, Window, int, XEvent *); +int (*XCheckWindowEvent_dylibloader_wrapper_xlib)(Display *, Window, long, XEvent *); +int (*XCirculateSubwindows_dylibloader_wrapper_xlib)(Display *, Window, int); +int (*XCirculateSubwindowsDown_dylibloader_wrapper_xlib)(Display *, Window); +int (*XCirculateSubwindowsUp_dylibloader_wrapper_xlib)(Display *, Window); +int (*XClearArea_dylibloader_wrapper_xlib)(Display *, Window, int, int, unsigned int, unsigned int, int); +int (*XClearWindow_dylibloader_wrapper_xlib)(Display *, Window); +int (*XCloseDisplay_dylibloader_wrapper_xlib)(Display *); +int (*XConfigureWindow_dylibloader_wrapper_xlib)(Display *, Window, unsigned int, XWindowChanges *); +int (*XConnectionNumber_dylibloader_wrapper_xlib)(Display *); +int (*XConvertSelection_dylibloader_wrapper_xlib)(Display *, Atom, Atom, Atom, Window, Time); +int (*XCopyArea_dylibloader_wrapper_xlib)(Display *, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int); +int (*XCopyGC_dylibloader_wrapper_xlib)(Display *, GC, unsigned long, GC); +int (*XCopyPlane_dylibloader_wrapper_xlib)(Display *, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int, unsigned long); +int (*XDefaultDepth_dylibloader_wrapper_xlib)(Display *, int); +int (*XDefaultDepthOfScreen_dylibloader_wrapper_xlib)(Screen *); +int (*XDefaultScreen_dylibloader_wrapper_xlib)(Display *); +int (*XDefineCursor_dylibloader_wrapper_xlib)(Display *, Window, Cursor); +int (*XDeleteProperty_dylibloader_wrapper_xlib)(Display *, Window, Atom); +int (*XDestroyWindow_dylibloader_wrapper_xlib)(Display *, Window); +int (*XDestroySubwindows_dylibloader_wrapper_xlib)(Display *, Window); +int (*XDoesBackingStore_dylibloader_wrapper_xlib)(Screen *); +int (*XDoesSaveUnders_dylibloader_wrapper_xlib)(Screen *); +int (*XDisableAccessControl_dylibloader_wrapper_xlib)(Display *); +int (*XDisplayCells_dylibloader_wrapper_xlib)(Display *, int); +int (*XDisplayHeight_dylibloader_wrapper_xlib)(Display *, int); +int (*XDisplayHeightMM_dylibloader_wrapper_xlib)(Display *, int); +int (*XDisplayKeycodes_dylibloader_wrapper_xlib)(Display *, int *, int *); +int (*XDisplayPlanes_dylibloader_wrapper_xlib)(Display *, int); +int (*XDisplayWidth_dylibloader_wrapper_xlib)(Display *, int); +int (*XDisplayWidthMM_dylibloader_wrapper_xlib)(Display *, int); +int (*XDrawArc_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, unsigned int, unsigned int, int, int); +int (*XDrawArcs_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XArc *, int); +int (*XDrawImageString_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, const char *, int); +int (*XDrawImageString16_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, const XChar2b *, int); +int (*XDrawLine_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, int, int); +int (*XDrawLines_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XPoint *, int, int); +int (*XDrawPoint_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int); +int (*XDrawPoints_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XPoint *, int, int); +int (*XDrawRectangle_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, unsigned int, unsigned int); +int (*XDrawRectangles_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XRectangle *, int); +int (*XDrawSegments_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XSegment *, int); +int (*XDrawString_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, const char *, int); +int (*XDrawString16_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, const XChar2b *, int); +int (*XDrawText_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, XTextItem *, int); +int (*XDrawText16_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, XTextItem16 *, int); +int (*XEnableAccessControl_dylibloader_wrapper_xlib)(Display *); +int (*XEventsQueued_dylibloader_wrapper_xlib)(Display *, int); +int (*XFetchName_dylibloader_wrapper_xlib)(Display *, Window, char **); +int (*XFillArc_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, unsigned int, unsigned int, int, int); +int (*XFillArcs_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XArc *, int); +int (*XFillPolygon_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XPoint *, int, int, int); +int (*XFillRectangle_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, unsigned int, unsigned int); +int (*XFillRectangles_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XRectangle *, int); +int (*XFlush_dylibloader_wrapper_xlib)(Display *); +int (*XForceScreenSaver_dylibloader_wrapper_xlib)(Display *, int); +int (*XFree_dylibloader_wrapper_xlib)(void *); +int (*XFreeColormap_dylibloader_wrapper_xlib)(Display *, Colormap); +int (*XFreeColors_dylibloader_wrapper_xlib)(Display *, Colormap, unsigned long *, int, unsigned long); +int (*XFreeCursor_dylibloader_wrapper_xlib)(Display *, Cursor); +int (*XFreeExtensionList_dylibloader_wrapper_xlib)(char **); +int (*XFreeFont_dylibloader_wrapper_xlib)(Display *, XFontStruct *); +int (*XFreeFontInfo_dylibloader_wrapper_xlib)(char **, XFontStruct *, int); +int (*XFreeFontNames_dylibloader_wrapper_xlib)(char **); +int (*XFreeFontPath_dylibloader_wrapper_xlib)(char **); +int (*XFreeGC_dylibloader_wrapper_xlib)(Display *, GC); +int (*XFreeModifiermap_dylibloader_wrapper_xlib)(XModifierKeymap *); +int (*XFreePixmap_dylibloader_wrapper_xlib)(Display *, Pixmap); +int (*XGeometry_dylibloader_wrapper_xlib)(Display *, int, const char *, const char *, unsigned int, unsigned int, unsigned int, int, int, int *, int *, int *, int *); +int (*XGetErrorDatabaseText_dylibloader_wrapper_xlib)(Display *, const char *, const char *, const char *, char *, int); +int (*XGetErrorText_dylibloader_wrapper_xlib)(Display *, int, char *, int); +int (*XGetFontProperty_dylibloader_wrapper_xlib)(XFontStruct *, Atom, unsigned long *); +int (*XGetGCValues_dylibloader_wrapper_xlib)(Display *, GC, unsigned long, XGCValues *); +int (*XGetGeometry_dylibloader_wrapper_xlib)(Display *, Drawable, Window *, int *, int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *); +int (*XGetIconName_dylibloader_wrapper_xlib)(Display *, Window, char **); +int (*XGetInputFocus_dylibloader_wrapper_xlib)(Display *, Window *, int *); +int (*XGetKeyboardControl_dylibloader_wrapper_xlib)(Display *, XKeyboardState *); +int (*XGetPointerControl_dylibloader_wrapper_xlib)(Display *, int *, int *, int *); +int (*XGetPointerMapping_dylibloader_wrapper_xlib)(Display *, unsigned char *, int); +int (*XGetScreenSaver_dylibloader_wrapper_xlib)(Display *, int *, int *, int *, int *); +int (*XGetTransientForHint_dylibloader_wrapper_xlib)(Display *, Window, Window *); +int (*XGetWindowProperty_dylibloader_wrapper_xlib)(Display *, Window, Atom, long, long, int, Atom, Atom *, int *, unsigned long *, unsigned long *, unsigned char **); +int (*XGetWindowAttributes_dylibloader_wrapper_xlib)(Display *, Window, XWindowAttributes *); +int (*XGrabButton_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, Window, int, unsigned int, int, int, Window, Cursor); +int (*XGrabKey_dylibloader_wrapper_xlib)(Display *, int, unsigned int, Window, int, int, int); +int (*XGrabKeyboard_dylibloader_wrapper_xlib)(Display *, Window, int, int, int, Time); +int (*XGrabPointer_dylibloader_wrapper_xlib)(Display *, Window, int, unsigned int, int, int, Window, Cursor, Time); +int (*XGrabServer_dylibloader_wrapper_xlib)(Display *); +int (*XHeightMMOfScreen_dylibloader_wrapper_xlib)(Screen *); +int (*XHeightOfScreen_dylibloader_wrapper_xlib)(Screen *); +int (*XIfEvent_dylibloader_wrapper_xlib)(Display *, XEvent *, int (*)(Display *, XEvent *, XPointer), XPointer); +int (*XImageByteOrder_dylibloader_wrapper_xlib)(Display *); +int (*XInstallColormap_dylibloader_wrapper_xlib)(Display *, Colormap); +KeyCode (*XKeysymToKeycode_dylibloader_wrapper_xlib)(Display *, KeySym); +int (*XKillClient_dylibloader_wrapper_xlib)(Display *, XID); +int (*XLookupColor_dylibloader_wrapper_xlib)(Display *, Colormap, const char *, XColor *, XColor *); +int (*XLowerWindow_dylibloader_wrapper_xlib)(Display *, Window); +int (*XMapRaised_dylibloader_wrapper_xlib)(Display *, Window); +int (*XMapSubwindows_dylibloader_wrapper_xlib)(Display *, Window); +int (*XMapWindow_dylibloader_wrapper_xlib)(Display *, Window); +int (*XMaskEvent_dylibloader_wrapper_xlib)(Display *, long, XEvent *); +int (*XMaxCmapsOfScreen_dylibloader_wrapper_xlib)(Screen *); +int (*XMinCmapsOfScreen_dylibloader_wrapper_xlib)(Screen *); +int (*XMoveResizeWindow_dylibloader_wrapper_xlib)(Display *, Window, int, int, unsigned int, unsigned int); +int (*XMoveWindow_dylibloader_wrapper_xlib)(Display *, Window, int, int); +int (*XNextEvent_dylibloader_wrapper_xlib)(Display *, XEvent *); +int (*XNoOp_dylibloader_wrapper_xlib)(Display *); +int (*XParseColor_dylibloader_wrapper_xlib)(Display *, Colormap, const char *, XColor *); +int (*XParseGeometry_dylibloader_wrapper_xlib)(const char *, int *, int *, unsigned int *, unsigned int *); +int (*XPeekEvent_dylibloader_wrapper_xlib)(Display *, XEvent *); +int (*XPeekIfEvent_dylibloader_wrapper_xlib)(Display *, XEvent *, int (*)(Display *, XEvent *, XPointer), XPointer); +int (*XPending_dylibloader_wrapper_xlib)(Display *); +int (*XPlanesOfScreen_dylibloader_wrapper_xlib)(Screen *); +int (*XProtocolRevision_dylibloader_wrapper_xlib)(Display *); +int (*XProtocolVersion_dylibloader_wrapper_xlib)(Display *); +int (*XPutBackEvent_dylibloader_wrapper_xlib)(Display *, XEvent *); +int (*XPutImage_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XImage *, int, int, int, int, unsigned int, unsigned int); +int (*XQLength_dylibloader_wrapper_xlib)(Display *); +int (*XQueryBestCursor_dylibloader_wrapper_xlib)(Display *, Drawable, unsigned int, unsigned int, unsigned int *, unsigned int *); +int (*XQueryBestSize_dylibloader_wrapper_xlib)(Display *, int, Drawable, unsigned int, unsigned int, unsigned int *, unsigned int *); +int (*XQueryBestStipple_dylibloader_wrapper_xlib)(Display *, Drawable, unsigned int, unsigned int, unsigned int *, unsigned int *); +int (*XQueryBestTile_dylibloader_wrapper_xlib)(Display *, Drawable, unsigned int, unsigned int, unsigned int *, unsigned int *); +int (*XQueryColor_dylibloader_wrapper_xlib)(Display *, Colormap, XColor *); +int (*XQueryColors_dylibloader_wrapper_xlib)(Display *, Colormap, XColor *, int); +int (*XQueryExtension_dylibloader_wrapper_xlib)(Display *, const char *, int *, int *, int *); +int (*XQueryKeymap_dylibloader_wrapper_xlib)(Display *, char [32]); +int (*XQueryPointer_dylibloader_wrapper_xlib)(Display *, Window, Window *, Window *, int *, int *, int *, int *, unsigned int *); +int (*XQueryTextExtents_dylibloader_wrapper_xlib)(Display *, XID, const char *, int, int *, int *, int *, XCharStruct *); +int (*XQueryTextExtents16_dylibloader_wrapper_xlib)(Display *, XID, const XChar2b *, int, int *, int *, int *, XCharStruct *); +int (*XQueryTree_dylibloader_wrapper_xlib)(Display *, Window, Window *, Window *, Window **, unsigned int *); +int (*XRaiseWindow_dylibloader_wrapper_xlib)(Display *, Window); +int (*XReadBitmapFile_dylibloader_wrapper_xlib)(Display *, Drawable, const char *, unsigned int *, unsigned int *, Pixmap *, int *, int *); +int (*XReadBitmapFileData_dylibloader_wrapper_xlib)(const char *, unsigned int *, unsigned int *, unsigned char **, int *, int *); +int (*XRebindKeysym_dylibloader_wrapper_xlib)(Display *, KeySym, KeySym *, int, const unsigned char *, int); +int (*XRecolorCursor_dylibloader_wrapper_xlib)(Display *, Cursor, XColor *, XColor *); +int (*XRefreshKeyboardMapping_dylibloader_wrapper_xlib)(XMappingEvent *); +int (*XRemoveFromSaveSet_dylibloader_wrapper_xlib)(Display *, Window); +int (*XRemoveHost_dylibloader_wrapper_xlib)(Display *, XHostAddress *); +int (*XRemoveHosts_dylibloader_wrapper_xlib)(Display *, XHostAddress *, int); +int (*XReparentWindow_dylibloader_wrapper_xlib)(Display *, Window, Window, int, int); +int (*XResetScreenSaver_dylibloader_wrapper_xlib)(Display *); +int (*XResizeWindow_dylibloader_wrapper_xlib)(Display *, Window, unsigned int, unsigned int); +int (*XRestackWindows_dylibloader_wrapper_xlib)(Display *, Window *, int); +int (*XRotateBuffers_dylibloader_wrapper_xlib)(Display *, int); +int (*XRotateWindowProperties_dylibloader_wrapper_xlib)(Display *, Window, Atom *, int, int); +int (*XScreenCount_dylibloader_wrapper_xlib)(Display *); +int (*XSelectInput_dylibloader_wrapper_xlib)(Display *, Window, long); +int (*XSendEvent_dylibloader_wrapper_xlib)(Display *, Window, int, long, XEvent *); +int (*XSetAccessControl_dylibloader_wrapper_xlib)(Display *, int); +int (*XSetArcMode_dylibloader_wrapper_xlib)(Display *, GC, int); +int (*XSetBackground_dylibloader_wrapper_xlib)(Display *, GC, unsigned long); +int (*XSetClipMask_dylibloader_wrapper_xlib)(Display *, GC, Pixmap); +int (*XSetClipOrigin_dylibloader_wrapper_xlib)(Display *, GC, int, int); +int (*XSetClipRectangles_dylibloader_wrapper_xlib)(Display *, GC, int, int, XRectangle *, int, int); +int (*XSetCloseDownMode_dylibloader_wrapper_xlib)(Display *, int); +int (*XSetCommand_dylibloader_wrapper_xlib)(Display *, Window, char **, int); +int (*XSetDashes_dylibloader_wrapper_xlib)(Display *, GC, int, const char *, int); +int (*XSetFillRule_dylibloader_wrapper_xlib)(Display *, GC, int); +int (*XSetFillStyle_dylibloader_wrapper_xlib)(Display *, GC, int); +int (*XSetFont_dylibloader_wrapper_xlib)(Display *, GC, Font); +int (*XSetFontPath_dylibloader_wrapper_xlib)(Display *, char **, int); +int (*XSetForeground_dylibloader_wrapper_xlib)(Display *, GC, unsigned long); +int (*XSetFunction_dylibloader_wrapper_xlib)(Display *, GC, int); +int (*XSetGraphicsExposures_dylibloader_wrapper_xlib)(Display *, GC, int); +int (*XSetIconName_dylibloader_wrapper_xlib)(Display *, Window, const char *); +int (*XSetInputFocus_dylibloader_wrapper_xlib)(Display *, Window, int, Time); +int (*XSetLineAttributes_dylibloader_wrapper_xlib)(Display *, GC, unsigned int, int, int, int); +int (*XSetModifierMapping_dylibloader_wrapper_xlib)(Display *, XModifierKeymap *); +int (*XSetPlaneMask_dylibloader_wrapper_xlib)(Display *, GC, unsigned long); +int (*XSetPointerMapping_dylibloader_wrapper_xlib)(Display *, const unsigned char *, int); +int (*XSetScreenSaver_dylibloader_wrapper_xlib)(Display *, int, int, int, int); +int (*XSetSelectionOwner_dylibloader_wrapper_xlib)(Display *, Atom, Window, Time); +int (*XSetState_dylibloader_wrapper_xlib)(Display *, GC, unsigned long, unsigned long, int, unsigned long); +int (*XSetStipple_dylibloader_wrapper_xlib)(Display *, GC, Pixmap); +int (*XSetSubwindowMode_dylibloader_wrapper_xlib)(Display *, GC, int); +int (*XSetTSOrigin_dylibloader_wrapper_xlib)(Display *, GC, int, int); +int (*XSetTile_dylibloader_wrapper_xlib)(Display *, GC, Pixmap); +int (*XSetWindowBackground_dylibloader_wrapper_xlib)(Display *, Window, unsigned long); +int (*XSetWindowBackgroundPixmap_dylibloader_wrapper_xlib)(Display *, Window, Pixmap); +int (*XSetWindowBorder_dylibloader_wrapper_xlib)(Display *, Window, unsigned long); +int (*XSetWindowBorderPixmap_dylibloader_wrapper_xlib)(Display *, Window, Pixmap); +int (*XSetWindowBorderWidth_dylibloader_wrapper_xlib)(Display *, Window, unsigned int); +int (*XSetWindowColormap_dylibloader_wrapper_xlib)(Display *, Window, Colormap); +int (*XStoreBuffer_dylibloader_wrapper_xlib)(Display *, const char *, int, int); +int (*XStoreBytes_dylibloader_wrapper_xlib)(Display *, const char *, int); +int (*XStoreColor_dylibloader_wrapper_xlib)(Display *, Colormap, XColor *); +int (*XStoreColors_dylibloader_wrapper_xlib)(Display *, Colormap, XColor *, int); +int (*XStoreName_dylibloader_wrapper_xlib)(Display *, Window, const char *); +int (*XStoreNamedColor_dylibloader_wrapper_xlib)(Display *, Colormap, const char *, unsigned long, int); +int (*XSync_dylibloader_wrapper_xlib)(Display *, int); +int (*XTextExtents_dylibloader_wrapper_xlib)(XFontStruct *, const char *, int, int *, int *, int *, XCharStruct *); +int (*XTextExtents16_dylibloader_wrapper_xlib)(XFontStruct *, const XChar2b *, int, int *, int *, int *, XCharStruct *); +int (*XTextWidth_dylibloader_wrapper_xlib)(XFontStruct *, const char *, int); +int (*XTextWidth16_dylibloader_wrapper_xlib)(XFontStruct *, const XChar2b *, int); +int (*XTranslateCoordinates_dylibloader_wrapper_xlib)(Display *, Window, Window, int, int, int *, int *, Window *); +int (*XUndefineCursor_dylibloader_wrapper_xlib)(Display *, Window); +int (*XUngrabButton_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, Window); +int (*XUngrabKey_dylibloader_wrapper_xlib)(Display *, int, unsigned int, Window); +int (*XUngrabKeyboard_dylibloader_wrapper_xlib)(Display *, Time); +int (*XUngrabPointer_dylibloader_wrapper_xlib)(Display *, Time); +int (*XUngrabServer_dylibloader_wrapper_xlib)(Display *); +int (*XUninstallColormap_dylibloader_wrapper_xlib)(Display *, Colormap); +int (*XUnloadFont_dylibloader_wrapper_xlib)(Display *, Font); +int (*XUnmapSubwindows_dylibloader_wrapper_xlib)(Display *, Window); +int (*XUnmapWindow_dylibloader_wrapper_xlib)(Display *, Window); +int (*XVendorRelease_dylibloader_wrapper_xlib)(Display *); +int (*XWarpPointer_dylibloader_wrapper_xlib)(Display *, Window, Window, int, int, unsigned int, unsigned int, int, int); +int (*XWidthMMOfScreen_dylibloader_wrapper_xlib)(Screen *); +int (*XWidthOfScreen_dylibloader_wrapper_xlib)(Screen *); +int (*XWindowEvent_dylibloader_wrapper_xlib)(Display *, Window, long, XEvent *); +int (*XWriteBitmapFile_dylibloader_wrapper_xlib)(Display *, const char *, Pixmap, unsigned int, unsigned int, int, int); +int (*XSupportsLocale_dylibloader_wrapper_xlib)(void); +char *(*XSetLocaleModifiers_dylibloader_wrapper_xlib)(const char *); +XOM (*XOpenOM_dylibloader_wrapper_xlib)(Display *, struct _XrmHashBucketRec *, const char *, const char *); +int (*XCloseOM_dylibloader_wrapper_xlib)(XOM); +char *(*XSetOMValues_dylibloader_wrapper_xlib)(XOM, ...); +char *(*XGetOMValues_dylibloader_wrapper_xlib)(XOM, ...); +Display *(*XDisplayOfOM_dylibloader_wrapper_xlib)(XOM); +char *(*XLocaleOfOM_dylibloader_wrapper_xlib)(XOM); +XOC (*XCreateOC_dylibloader_wrapper_xlib)(XOM, ...); +void (*XDestroyOC_dylibloader_wrapper_xlib)(XOC); +XOM (*XOMOfOC_dylibloader_wrapper_xlib)(XOC); +char *(*XSetOCValues_dylibloader_wrapper_xlib)(XOC, ...); +char *(*XGetOCValues_dylibloader_wrapper_xlib)(XOC, ...); +XFontSet (*XCreateFontSet_dylibloader_wrapper_xlib)(Display *, const char *, char ***, int *, char **); +void (*XFreeFontSet_dylibloader_wrapper_xlib)(Display *, XFontSet); +int (*XFontsOfFontSet_dylibloader_wrapper_xlib)(XFontSet, XFontStruct ***, char ***); +char *(*XBaseFontNameListOfFontSet_dylibloader_wrapper_xlib)(XFontSet); +char *(*XLocaleOfFontSet_dylibloader_wrapper_xlib)(XFontSet); +int (*XContextDependentDrawing_dylibloader_wrapper_xlib)(XFontSet); +int (*XDirectionalDependentDrawing_dylibloader_wrapper_xlib)(XFontSet); +int (*XContextualDrawing_dylibloader_wrapper_xlib)(XFontSet); +XFontSetExtents *(*XExtentsOfFontSet_dylibloader_wrapper_xlib)(XFontSet); +int (*XmbTextEscapement_dylibloader_wrapper_xlib)(XFontSet, const char *, int); +int (*XwcTextEscapement_dylibloader_wrapper_xlib)(XFontSet, const wchar_t *, int); +int (*Xutf8TextEscapement_dylibloader_wrapper_xlib)(XFontSet, const char *, int); +int (*XmbTextExtents_dylibloader_wrapper_xlib)(XFontSet, const char *, int, XRectangle *, XRectangle *); +int (*XwcTextExtents_dylibloader_wrapper_xlib)(XFontSet, const wchar_t *, int, XRectangle *, XRectangle *); +int (*Xutf8TextExtents_dylibloader_wrapper_xlib)(XFontSet, const char *, int, XRectangle *, XRectangle *); +int (*XmbTextPerCharExtents_dylibloader_wrapper_xlib)(XFontSet, const char *, int, XRectangle *, XRectangle *, int, int *, XRectangle *, XRectangle *); +int (*XwcTextPerCharExtents_dylibloader_wrapper_xlib)(XFontSet, const wchar_t *, int, XRectangle *, XRectangle *, int, int *, XRectangle *, XRectangle *); +int (*Xutf8TextPerCharExtents_dylibloader_wrapper_xlib)(XFontSet, const char *, int, XRectangle *, XRectangle *, int, int *, XRectangle *, XRectangle *); +void (*XmbDrawText_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, XmbTextItem *, int); +void (*XwcDrawText_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, XwcTextItem *, int); +void (*Xutf8DrawText_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, XmbTextItem *, int); +void (*XmbDrawString_dylibloader_wrapper_xlib)(Display *, Drawable, XFontSet, GC, int, int, const char *, int); +void (*XwcDrawString_dylibloader_wrapper_xlib)(Display *, Drawable, XFontSet, GC, int, int, const wchar_t *, int); +void (*Xutf8DrawString_dylibloader_wrapper_xlib)(Display *, Drawable, XFontSet, GC, int, int, const char *, int); +void (*XmbDrawImageString_dylibloader_wrapper_xlib)(Display *, Drawable, XFontSet, GC, int, int, const char *, int); +void (*XwcDrawImageString_dylibloader_wrapper_xlib)(Display *, Drawable, XFontSet, GC, int, int, const wchar_t *, int); +void (*Xutf8DrawImageString_dylibloader_wrapper_xlib)(Display *, Drawable, XFontSet, GC, int, int, const char *, int); +XIM (*XOpenIM_dylibloader_wrapper_xlib)(Display *, struct _XrmHashBucketRec *, char *, char *); +int (*XCloseIM_dylibloader_wrapper_xlib)(XIM); +char *(*XGetIMValues_dylibloader_wrapper_xlib)(XIM, ...); +char *(*XSetIMValues_dylibloader_wrapper_xlib)(XIM, ...); +Display *(*XDisplayOfIM_dylibloader_wrapper_xlib)(XIM); +char *(*XLocaleOfIM_dylibloader_wrapper_xlib)(XIM); +XIC (*XCreateIC_dylibloader_wrapper_xlib)(XIM, ...); +void (*XDestroyIC_dylibloader_wrapper_xlib)(XIC); +void (*XSetICFocus_dylibloader_wrapper_xlib)(XIC); +void (*XUnsetICFocus_dylibloader_wrapper_xlib)(XIC); +wchar_t *(*XwcResetIC_dylibloader_wrapper_xlib)(XIC); +char *(*XmbResetIC_dylibloader_wrapper_xlib)(XIC); +char *(*Xutf8ResetIC_dylibloader_wrapper_xlib)(XIC); +char *(*XSetICValues_dylibloader_wrapper_xlib)(XIC, ...); +char *(*XGetICValues_dylibloader_wrapper_xlib)(XIC, ...); +XIM (*XIMOfIC_dylibloader_wrapper_xlib)(XIC); +int (*XFilterEvent_dylibloader_wrapper_xlib)(XEvent *, Window); +int (*XmbLookupString_dylibloader_wrapper_xlib)(XIC, XKeyPressedEvent *, char *, int, KeySym *, int *); +int (*XwcLookupString_dylibloader_wrapper_xlib)(XIC, XKeyPressedEvent *, wchar_t *, int, KeySym *, int *); +int (*Xutf8LookupString_dylibloader_wrapper_xlib)(XIC, XKeyPressedEvent *, char *, int, KeySym *, int *); +XVaNestedList (*XVaCreateNestedList_dylibloader_wrapper_xlib)(int, ...); +int (*XRegisterIMInstantiateCallback_dylibloader_wrapper_xlib)(Display *, struct _XrmHashBucketRec *, char *, char *, XIDProc, XPointer); +int (*XUnregisterIMInstantiateCallback_dylibloader_wrapper_xlib)(Display *, struct _XrmHashBucketRec *, char *, char *, XIDProc, XPointer); +int (*XInternalConnectionNumbers_dylibloader_wrapper_xlib)(Display *, int **, int *); +void (*XProcessInternalConnection_dylibloader_wrapper_xlib)(Display *, int); +int (*XAddConnectionWatch_dylibloader_wrapper_xlib)(Display *, XConnectionWatchProc, XPointer); +void (*XRemoveConnectionWatch_dylibloader_wrapper_xlib)(Display *, XConnectionWatchProc, XPointer); +void (*XSetAuthorization_dylibloader_wrapper_xlib)(char *, int, char *, int); +int (*_Xmbtowc_dylibloader_wrapper_xlib)(wchar_t *, char *, int); +int (*_Xwctomb_dylibloader_wrapper_xlib)(char *, wchar_t); +int (*XGetEventData_dylibloader_wrapper_xlib)(Display *, XGenericEventCookie *); +void (*XFreeEventData_dylibloader_wrapper_xlib)(Display *, XGenericEventCookie *); +int (*XFreeThreads_dylibloader_wrapper_xlib)(void); +XClassHint *(*XAllocClassHint_dylibloader_wrapper_xlib)(void); +XIconSize *(*XAllocIconSize_dylibloader_wrapper_xlib)(void); +XSizeHints *(*XAllocSizeHints_dylibloader_wrapper_xlib)(void); +XStandardColormap *(*XAllocStandardColormap_dylibloader_wrapper_xlib)(void); +XWMHints *(*XAllocWMHints_dylibloader_wrapper_xlib)(void); +int (*XClipBox_dylibloader_wrapper_xlib)(Region, XRectangle *); +Region (*XCreateRegion_dylibloader_wrapper_xlib)(void); +const char *(*XDefaultString_dylibloader_wrapper_xlib)(void); +int (*XDeleteContext_dylibloader_wrapper_xlib)(Display *, XID, XContext); +int (*XDestroyRegion_dylibloader_wrapper_xlib)(Region); +int (*XEmptyRegion_dylibloader_wrapper_xlib)(Region); +int (*XEqualRegion_dylibloader_wrapper_xlib)(Region, Region); +int (*XFindContext_dylibloader_wrapper_xlib)(Display *, XID, XContext, XPointer *); +int (*XGetClassHint_dylibloader_wrapper_xlib)(Display *, Window, XClassHint *); +int (*XGetIconSizes_dylibloader_wrapper_xlib)(Display *, Window, XIconSize **, int *); +int (*XGetNormalHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *); +int (*XGetRGBColormaps_dylibloader_wrapper_xlib)(Display *, Window, XStandardColormap **, int *, Atom); +int (*XGetSizeHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *, Atom); +int (*XGetStandardColormap_dylibloader_wrapper_xlib)(Display *, Window, XStandardColormap *, Atom); +int (*XGetTextProperty_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *, Atom); +XVisualInfo *(*XGetVisualInfo_dylibloader_wrapper_xlib)(Display *, long, XVisualInfo *, int *); +int (*XGetWMClientMachine_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *); +XWMHints *(*XGetWMHints_dylibloader_wrapper_xlib)(Display *, Window); +int (*XGetWMIconName_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *); +int (*XGetWMName_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *); +int (*XGetWMNormalHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *, long *); +int (*XGetWMSizeHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *, long *, Atom); +int (*XGetZoomHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *); +int (*XIntersectRegion_dylibloader_wrapper_xlib)(Region, Region, Region); +void (*XConvertCase_dylibloader_wrapper_xlib)(KeySym, KeySym *, KeySym *); +int (*XLookupString_dylibloader_wrapper_xlib)(XKeyEvent *, char *, int, KeySym *, XComposeStatus *); +int (*XMatchVisualInfo_dylibloader_wrapper_xlib)(Display *, int, int, int, XVisualInfo *); +int (*XOffsetRegion_dylibloader_wrapper_xlib)(Region, int, int); +int (*XPointInRegion_dylibloader_wrapper_xlib)(Region, int, int); +Region (*XPolygonRegion_dylibloader_wrapper_xlib)(XPoint *, int, int); +int (*XRectInRegion_dylibloader_wrapper_xlib)(Region, int, int, unsigned int, unsigned int); +int (*XSaveContext_dylibloader_wrapper_xlib)(Display *, XID, XContext, const char *); +int (*XSetClassHint_dylibloader_wrapper_xlib)(Display *, Window, XClassHint *); +int (*XSetIconSizes_dylibloader_wrapper_xlib)(Display *, Window, XIconSize *, int); +int (*XSetNormalHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *); +void (*XSetRGBColormaps_dylibloader_wrapper_xlib)(Display *, Window, XStandardColormap *, int, Atom); +int (*XSetSizeHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *, Atom); +int (*XSetStandardProperties_dylibloader_wrapper_xlib)(Display *, Window, const char *, const char *, Pixmap, char **, int, XSizeHints *); +void (*XSetTextProperty_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *, Atom); +void (*XSetWMClientMachine_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *); +int (*XSetWMHints_dylibloader_wrapper_xlib)(Display *, Window, XWMHints *); +void (*XSetWMIconName_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *); +void (*XSetWMName_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *); +void (*XSetWMNormalHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *); +void (*XSetWMProperties_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *, XTextProperty *, char **, int, XSizeHints *, XWMHints *, XClassHint *); +void (*XmbSetWMProperties_dylibloader_wrapper_xlib)(Display *, Window, const char *, const char *, char **, int, XSizeHints *, XWMHints *, XClassHint *); +void (*Xutf8SetWMProperties_dylibloader_wrapper_xlib)(Display *, Window, const char *, const char *, char **, int, XSizeHints *, XWMHints *, XClassHint *); +void (*XSetWMSizeHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *, Atom); +int (*XSetRegion_dylibloader_wrapper_xlib)(Display *, GC, Region); +void (*XSetStandardColormap_dylibloader_wrapper_xlib)(Display *, Window, XStandardColormap *, Atom); +int (*XSetZoomHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *); +int (*XShrinkRegion_dylibloader_wrapper_xlib)(Region, int, int); +int (*XStringListToTextProperty_dylibloader_wrapper_xlib)(char **, int, XTextProperty *); +int (*XSubtractRegion_dylibloader_wrapper_xlib)(Region, Region, Region); +int (*XmbTextListToTextProperty_dylibloader_wrapper_xlib)(Display *, char **, int, XICCEncodingStyle, XTextProperty *); +int (*XwcTextListToTextProperty_dylibloader_wrapper_xlib)(Display *, wchar_t **, int, XICCEncodingStyle, XTextProperty *); +int (*Xutf8TextListToTextProperty_dylibloader_wrapper_xlib)(Display *, char **, int, XICCEncodingStyle, XTextProperty *); +void (*XwcFreeStringList_dylibloader_wrapper_xlib)(wchar_t **); +int (*XTextPropertyToStringList_dylibloader_wrapper_xlib)(XTextProperty *, char ***, int *); +int (*XmbTextPropertyToTextList_dylibloader_wrapper_xlib)(Display *, const XTextProperty *, char ***, int *); +int (*XwcTextPropertyToTextList_dylibloader_wrapper_xlib)(Display *, const XTextProperty *, wchar_t ***, int *); +int (*Xutf8TextPropertyToTextList_dylibloader_wrapper_xlib)(Display *, const XTextProperty *, char ***, int *); +int (*XUnionRectWithRegion_dylibloader_wrapper_xlib)(XRectangle *, Region, Region); +int (*XUnionRegion_dylibloader_wrapper_xlib)(Region, Region, Region); +int (*XWMGeometry_dylibloader_wrapper_xlib)(Display *, int, const char *, const char *, unsigned int, XSizeHints *, int *, int *, int *, int *, int *); +int (*XXorRegion_dylibloader_wrapper_xlib)(Region, Region, Region); +int (*XkbIgnoreExtension_dylibloader_wrapper_xlib)(int); +Display *(*XkbOpenDisplay_dylibloader_wrapper_xlib)(char *, int *, int *, int *, int *, int *); +int (*XkbQueryExtension_dylibloader_wrapper_xlib)(Display *, int *, int *, int *, int *, int *); +int (*XkbUseExtension_dylibloader_wrapper_xlib)(Display *, int *, int *); +int (*XkbLibraryVersion_dylibloader_wrapper_xlib)(int *, int *); +unsigned int (*XkbSetXlibControls_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int); +unsigned int (*XkbGetXlibControls_dylibloader_wrapper_xlib)(Display *); +unsigned int (*XkbXlibControlsImplemented_dylibloader_wrapper_xlib)(void); +void (*XkbSetAtomFuncs_dylibloader_wrapper_xlib)(XkbInternAtomFunc, XkbGetAtomNameFunc); +KeySym (*XkbKeycodeToKeysym_dylibloader_wrapper_xlib)(Display *, KeyCode, int, int); +unsigned int (*XkbKeysymToModifiers_dylibloader_wrapper_xlib)(Display *, KeySym); +int (*XkbLookupKeySym_dylibloader_wrapper_xlib)(Display *, KeyCode, unsigned int, unsigned int *, KeySym *); +int (*XkbLookupKeyBinding_dylibloader_wrapper_xlib)(Display *, KeySym, unsigned int, char *, int, int *); +int (*XkbTranslateKeyCode_dylibloader_wrapper_xlib)(XkbDescPtr, KeyCode, unsigned int, unsigned int *, KeySym *); +int (*XkbTranslateKeySym_dylibloader_wrapper_xlib)(Display *, KeySym *, unsigned int, char *, int, int *); +int (*XkbSetAutoRepeatRate_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int); +int (*XkbGetAutoRepeatRate_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int *, unsigned int *); +int (*XkbChangeEnabledControls_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int); +int (*XkbDeviceBell_dylibloader_wrapper_xlib)(Display *, Window, int, int, int, int, Atom); +int (*XkbForceDeviceBell_dylibloader_wrapper_xlib)(Display *, int, int, int, int); +int (*XkbDeviceBellEvent_dylibloader_wrapper_xlib)(Display *, Window, int, int, int, int, Atom); +int (*XkbBell_dylibloader_wrapper_xlib)(Display *, Window, int, Atom); +int (*XkbForceBell_dylibloader_wrapper_xlib)(Display *, int); +int (*XkbBellEvent_dylibloader_wrapper_xlib)(Display *, Window, int, Atom); +int (*XkbSelectEvents_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int); +int (*XkbSelectEventDetails_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned long, unsigned long); +void (*XkbNoteMapChanges_dylibloader_wrapper_xlib)(XkbMapChangesPtr, XkbMapNotifyEvent *, unsigned int); +void (*XkbNoteNameChanges_dylibloader_wrapper_xlib)(XkbNameChangesPtr, XkbNamesNotifyEvent *, unsigned int); +int (*XkbGetIndicatorState_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int *); +int (*XkbGetIndicatorMap_dylibloader_wrapper_xlib)(Display *, unsigned long, XkbDescPtr); +int (*XkbSetIndicatorMap_dylibloader_wrapper_xlib)(Display *, unsigned long, XkbDescPtr); +int (*XkbGetNamedIndicator_dylibloader_wrapper_xlib)(Display *, Atom, int *, int *, XkbIndicatorMapPtr, int *); +int (*XkbGetNamedDeviceIndicator_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int, Atom, int *, int *, XkbIndicatorMapPtr, int *); +int (*XkbSetNamedIndicator_dylibloader_wrapper_xlib)(Display *, Atom, int, int, int, XkbIndicatorMapPtr); +int (*XkbSetNamedDeviceIndicator_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int, Atom, int, int, int, XkbIndicatorMapPtr); +int (*XkbLockModifiers_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int); +int (*XkbLatchModifiers_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int); +int (*XkbLockGroup_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int); +int (*XkbLatchGroup_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int); +int (*XkbSetServerInternalMods_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); +int (*XkbSetIgnoreLockMods_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); +int (*XkbVirtualModsToReal_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, unsigned int *); +int (*XkbComputeEffectiveMap_dylibloader_wrapper_xlib)(XkbDescPtr, XkbKeyTypePtr, unsigned char *); +int (*XkbInitCanonicalKeyTypes_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int); +XkbDescPtr (*XkbAllocKeyboard_dylibloader_wrapper_xlib)(void); +void (*XkbFreeKeyboard_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int); +int (*XkbAllocClientMap_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, unsigned int); +int (*XkbAllocServerMap_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, unsigned int); +void (*XkbFreeClientMap_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int); +void (*XkbFreeServerMap_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int); +XkbKeyTypePtr (*XkbAddKeyType_dylibloader_wrapper_xlib)(XkbDescPtr, Atom, int, int, int); +int (*XkbAllocIndicatorMaps_dylibloader_wrapper_xlib)(XkbDescPtr); +void (*XkbFreeIndicatorMaps_dylibloader_wrapper_xlib)(XkbDescPtr); +XkbDescPtr (*XkbGetMap_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int); +int (*XkbGetUpdatedMap_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbDescPtr); +int (*XkbGetMapChanges_dylibloader_wrapper_xlib)(Display *, XkbDescPtr, XkbMapChangesPtr); +int (*XkbRefreshKeyboardMapping_dylibloader_wrapper_xlib)(XkbMapNotifyEvent *); +int (*XkbGetKeyTypes_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, XkbDescPtr); +int (*XkbGetKeySyms_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, XkbDescPtr); +int (*XkbGetKeyActions_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, XkbDescPtr); +int (*XkbGetKeyBehaviors_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, XkbDescPtr); +int (*XkbGetVirtualMods_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbDescPtr); +int (*XkbGetKeyExplicitComponents_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, XkbDescPtr); +int (*XkbGetKeyModifierMap_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, XkbDescPtr); +int (*XkbGetKeyVirtualModMap_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, XkbDescPtr); +int (*XkbAllocControls_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int); +void (*XkbFreeControls_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int); +int (*XkbGetControls_dylibloader_wrapper_xlib)(Display *, unsigned long, XkbDescPtr); +int (*XkbSetControls_dylibloader_wrapper_xlib)(Display *, unsigned long, XkbDescPtr); +void (*XkbNoteControlsChanges_dylibloader_wrapper_xlib)(XkbControlsChangesPtr, XkbControlsNotifyEvent *, unsigned int); +int (*XkbAllocCompatMap_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, unsigned int); +void (*XkbFreeCompatMap_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int); +int (*XkbGetCompatMap_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbDescPtr); +int (*XkbSetCompatMap_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbDescPtr, int); +int (*XkbAllocNames_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int, int); +int (*XkbGetNames_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbDescPtr); +int (*XkbSetNames_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int, XkbDescPtr); +int (*XkbChangeNames_dylibloader_wrapper_xlib)(Display *, XkbDescPtr, XkbNameChangesPtr); +void (*XkbFreeNames_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int); +int (*XkbGetState_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbStatePtr); +int (*XkbSetMap_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbDescPtr); +int (*XkbChangeMap_dylibloader_wrapper_xlib)(Display *, XkbDescPtr, XkbMapChangesPtr); +int (*XkbSetDetectableAutoRepeat_dylibloader_wrapper_xlib)(Display *, int, int *); +int (*XkbGetDetectableAutoRepeat_dylibloader_wrapper_xlib)(Display *, int *); +int (*XkbSetAutoResetControls_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int *, unsigned int *); +int (*XkbGetAutoResetControls_dylibloader_wrapper_xlib)(Display *, unsigned int *, unsigned int *); +int (*XkbSetPerClientControls_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int *); +int (*XkbGetPerClientControls_dylibloader_wrapper_xlib)(Display *, unsigned int *); +int (*XkbCopyKeyType_dylibloader_wrapper_xlib)(XkbKeyTypePtr, XkbKeyTypePtr); +int (*XkbCopyKeyTypes_dylibloader_wrapper_xlib)(XkbKeyTypePtr, XkbKeyTypePtr, int); +int (*XkbResizeKeyType_dylibloader_wrapper_xlib)(XkbDescPtr, int, int, int, int); +KeySym *(*XkbResizeKeySyms_dylibloader_wrapper_xlib)(XkbDescPtr, int, int); +XkbAction *(*XkbResizeKeyActions_dylibloader_wrapper_xlib)(XkbDescPtr, int, int); +int (*XkbChangeTypesOfKey_dylibloader_wrapper_xlib)(XkbDescPtr, int, int, unsigned int, int *, XkbMapChangesPtr); +int (*XkbChangeKeycodeRange_dylibloader_wrapper_xlib)(XkbDescPtr, int, int, XkbChangesPtr); +XkbComponentListPtr (*XkbListComponents_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbComponentNamesPtr, int *); +void (*XkbFreeComponentList_dylibloader_wrapper_xlib)(XkbComponentListPtr); +XkbDescPtr (*XkbGetKeyboard_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int); +XkbDescPtr (*XkbGetKeyboardByName_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbComponentNamesPtr, unsigned int, unsigned int, int); +int (*XkbKeyTypesForCoreSymbols_dylibloader_wrapper_xlib)(XkbDescPtr, int, KeySym *, unsigned int, int *, KeySym *); +int (*XkbApplyCompatMapToKey_dylibloader_wrapper_xlib)(XkbDescPtr, KeyCode, XkbChangesPtr); +int (*XkbUpdateMapFromCore_dylibloader_wrapper_xlib)(XkbDescPtr, KeyCode, int, int, KeySym *, XkbChangesPtr); +XkbDeviceLedInfoPtr (*XkbAddDeviceLedInfo_dylibloader_wrapper_xlib)(XkbDeviceInfoPtr, unsigned int, unsigned int); +int (*XkbResizeDeviceButtonActions_dylibloader_wrapper_xlib)(XkbDeviceInfoPtr, unsigned int); +XkbDeviceInfoPtr (*XkbAllocDeviceInfo_dylibloader_wrapper_xlib)(unsigned int, unsigned int, unsigned int); +void (*XkbFreeDeviceInfo_dylibloader_wrapper_xlib)(XkbDeviceInfoPtr, unsigned int, int); +void (*XkbNoteDeviceChanges_dylibloader_wrapper_xlib)(XkbDeviceChangesPtr, XkbExtensionDeviceNotifyEvent *, unsigned int); +XkbDeviceInfoPtr (*XkbGetDeviceInfo_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int, unsigned int); +int (*XkbGetDeviceInfoChanges_dylibloader_wrapper_xlib)(Display *, XkbDeviceInfoPtr, XkbDeviceChangesPtr); +int (*XkbGetDeviceButtonActions_dylibloader_wrapper_xlib)(Display *, XkbDeviceInfoPtr, int, unsigned int, unsigned int); +int (*XkbGetDeviceLedInfo_dylibloader_wrapper_xlib)(Display *, XkbDeviceInfoPtr, unsigned int, unsigned int, unsigned int); +int (*XkbSetDeviceInfo_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbDeviceInfoPtr); +int (*XkbChangeDeviceInfo_dylibloader_wrapper_xlib)(Display *, XkbDeviceInfoPtr, XkbDeviceChangesPtr); +int (*XkbSetDeviceLedInfo_dylibloader_wrapper_xlib)(Display *, XkbDeviceInfoPtr, unsigned int, unsigned int, unsigned int); +int (*XkbSetDeviceButtonActions_dylibloader_wrapper_xlib)(Display *, XkbDeviceInfoPtr, unsigned int, unsigned int); +char (*XkbToControl_dylibloader_wrapper_xlib)(char); +int (*XkbSetDebuggingFlags_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, char *, unsigned int, unsigned int, unsigned int *, unsigned int *); +int (*XkbApplyVirtualModChanges_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, XkbChangesPtr); +int (*XkbUpdateActionVirtualMods_dylibloader_wrapper_xlib)(XkbDescPtr, XkbAction *, unsigned int); +void (*XkbUpdateKeyTypeVirtualMods_dylibloader_wrapper_xlib)(XkbDescPtr, XkbKeyTypePtr, unsigned int, XkbChangesPtr); int initialize_xlib(int verbose) { void *handle; char *error; @@ -2548,6 +2548,14 @@ int initialize_xlib(int verbose) { fprintf(stderr, "%s\n", error); } } +// XSetIOErrorExitHandler + *(void **) (&XSetIOErrorExitHandler_dylibloader_wrapper_xlib) = dlsym(handle, "XSetIOErrorExitHandler"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } // XListPixmapFormats *(void **) (&XListPixmapFormats_dylibloader_wrapper_xlib) = dlsym(handle, "XListPixmapFormats"); if (verbose) { @@ -5132,6 +5140,14 @@ int initialize_xlib(int verbose) { fprintf(stderr, "%s\n", error); } } +// XFreeThreads + *(void **) (&XFreeThreads_dylibloader_wrapper_xlib) = dlsym(handle, "XFreeThreads"); + if (verbose) { + error = dlerror(); + if (error != NULL) { + fprintf(stderr, "%s\n", error); + } + } // XAllocClassHint *(void **) (&XAllocClassHint_dylibloader_wrapper_xlib) = dlsym(handle, "XAllocClassHint"); if (verbose) { diff --git a/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h index 5bad21002d..3f556a7cda 100644 --- a/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h +++ b/platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h @@ -2,16 +2,9 @@ #define DYLIBLOAD_WRAPPER_XLIB // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by generate-wrapper.py 0.3 on 2023-01-23 15:13:26 -// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xlib.h --include ./thirdparty/linuxbsd_headers/X11/Xutil.h --include ./thirdparty/linuxbsd_headers/X11/XKBlib.h --sys-include "thirdparty/linuxbsd_headers/X11/Xlib.h" --sys-include "thirdparty/linuxbsd_headers/X11/Xutil.h" --sys-include "thirdparty/linuxbsd_headers/X11/XKBlib.h" --soname libX11.so.6 --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c~ +// generated by generate-wrapper.py 0.6 on 2024-11-09 02:52:36 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/Xlib.h --include ./thirdparty/linuxbsd_headers/X11/Xutil.h --include ./thirdparty/linuxbsd_headers/X11/XKBlib.h --sys-include thirdparty/linuxbsd_headers/X11/Xlib.h --sys-include thirdparty/linuxbsd_headers/X11/Xutil.h --sys-include thirdparty/linuxbsd_headers/X11/XKBlib.h --soname libX11.so.6 --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xlib-so_wrap.c // -// NOTE: Generated from Xlib 1.6.9. -// This has been handpatched to workaround some issues with the generator that -// will be eventually fixed. In this case, the type of the third argument of -// XIfEvent, XPeekIfEvent and XCheckIfEvent had to be fixed as it wasn't parsed -// fully (it's a Bool function pointer, but it was just being parsed as an int -// pointer). - #include <stdint.h> #define _Xmblen _Xmblen_dylibloader_orig_xlib @@ -103,6 +96,7 @@ #define XScreenNumberOfScreen XScreenNumberOfScreen_dylibloader_orig_xlib #define XSetErrorHandler XSetErrorHandler_dylibloader_orig_xlib #define XSetIOErrorHandler XSetIOErrorHandler_dylibloader_orig_xlib +#define XSetIOErrorExitHandler XSetIOErrorExitHandler_dylibloader_orig_xlib #define XListPixmapFormats XListPixmapFormats_dylibloader_orig_xlib #define XListDepths XListDepths_dylibloader_orig_xlib #define XReconfigureWMWindow XReconfigureWMWindow_dylibloader_orig_xlib @@ -426,6 +420,7 @@ #define _Xwctomb _Xwctomb_dylibloader_orig_xlib #define XGetEventData XGetEventData_dylibloader_orig_xlib #define XFreeEventData XFreeEventData_dylibloader_orig_xlib +#define XFreeThreads XFreeThreads_dylibloader_orig_xlib #define XAllocClassHint XAllocClassHint_dylibloader_orig_xlib #define XAllocIconSize XAllocIconSize_dylibloader_orig_xlib #define XAllocSizeHints XAllocSizeHints_dylibloader_orig_xlib @@ -709,6 +704,7 @@ #undef XScreenNumberOfScreen #undef XSetErrorHandler #undef XSetIOErrorHandler +#undef XSetIOErrorExitHandler #undef XListPixmapFormats #undef XListDepths #undef XReconfigureWMWindow @@ -1032,6 +1028,7 @@ #undef _Xwctomb #undef XGetEventData #undef XFreeEventData +#undef XFreeThreads #undef XAllocClassHint #undef XAllocIconSize #undef XAllocSizeHints @@ -1315,6 +1312,7 @@ extern "C" { #define XScreenNumberOfScreen XScreenNumberOfScreen_dylibloader_wrapper_xlib #define XSetErrorHandler XSetErrorHandler_dylibloader_wrapper_xlib #define XSetIOErrorHandler XSetIOErrorHandler_dylibloader_wrapper_xlib +#define XSetIOErrorExitHandler XSetIOErrorExitHandler_dylibloader_wrapper_xlib #define XListPixmapFormats XListPixmapFormats_dylibloader_wrapper_xlib #define XListDepths XListDepths_dylibloader_wrapper_xlib #define XReconfigureWMWindow XReconfigureWMWindow_dylibloader_wrapper_xlib @@ -1638,6 +1636,7 @@ extern "C" { #define _Xwctomb _Xwctomb_dylibloader_wrapper_xlib #define XGetEventData XGetEventData_dylibloader_wrapper_xlib #define XFreeEventData XFreeEventData_dylibloader_wrapper_xlib +#define XFreeThreads XFreeThreads_dylibloader_wrapper_xlib #define XAllocClassHint XAllocClassHint_dylibloader_wrapper_xlib #define XAllocIconSize XAllocIconSize_dylibloader_wrapper_xlib #define XAllocSizeHints XAllocSizeHints_dylibloader_wrapper_xlib @@ -1829,609 +1828,611 @@ extern "C" { #define XkbApplyVirtualModChanges XkbApplyVirtualModChanges_dylibloader_wrapper_xlib #define XkbUpdateActionVirtualMods XkbUpdateActionVirtualMods_dylibloader_wrapper_xlib #define XkbUpdateKeyTypeVirtualMods XkbUpdateKeyTypeVirtualMods_dylibloader_wrapper_xlib -extern int (*_Xmblen_dylibloader_wrapper_xlib)( char*, int); -extern XFontStruct* (*XLoadQueryFont_dylibloader_wrapper_xlib)( Display*,const char*); -extern XFontStruct* (*XQueryFont_dylibloader_wrapper_xlib)( Display*, XID); -extern XTimeCoord* (*XGetMotionEvents_dylibloader_wrapper_xlib)( Display*, Window, Time, Time, int*); -extern XModifierKeymap* (*XDeleteModifiermapEntry_dylibloader_wrapper_xlib)( XModifierKeymap*, KeyCode, int); -extern XModifierKeymap* (*XGetModifierMapping_dylibloader_wrapper_xlib)( Display*); -extern XModifierKeymap* (*XInsertModifiermapEntry_dylibloader_wrapper_xlib)( XModifierKeymap*, KeyCode, int); -extern XModifierKeymap* (*XNewModifiermap_dylibloader_wrapper_xlib)( int); -extern XImage* (*XCreateImage_dylibloader_wrapper_xlib)( Display*, Visual*, unsigned int, int, int, char*, unsigned int, unsigned int, int, int); -extern int (*XInitImage_dylibloader_wrapper_xlib)( XImage*); -extern XImage* (*XGetImage_dylibloader_wrapper_xlib)( Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int); -extern XImage* (*XGetSubImage_dylibloader_wrapper_xlib)( Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int, XImage*, int, int); -extern Display* (*XOpenDisplay_dylibloader_wrapper_xlib)(const char*); -extern void (*XrmInitialize_dylibloader_wrapper_xlib)( void); -extern char* (*XFetchBytes_dylibloader_wrapper_xlib)( Display*, int*); -extern char* (*XFetchBuffer_dylibloader_wrapper_xlib)( Display*, int*, int); -extern char* (*XGetAtomName_dylibloader_wrapper_xlib)( Display*, Atom); -extern int (*XGetAtomNames_dylibloader_wrapper_xlib)( Display*, Atom*, int, char**); -extern char* (*XGetDefault_dylibloader_wrapper_xlib)( Display*,const char*,const char*); -extern char* (*XDisplayName_dylibloader_wrapper_xlib)(const char*); -extern char* (*XKeysymToString_dylibloader_wrapper_xlib)( KeySym); -extern int* (*XSynchronize_dylibloader_wrapper_xlib)( Display*, int); -extern int* (*XSetAfterFunction_dylibloader_wrapper_xlib)( Display*, int*); -extern Atom (*XInternAtom_dylibloader_wrapper_xlib)( Display*,const char*, int); -extern int (*XInternAtoms_dylibloader_wrapper_xlib)( Display*, char**, int, int, Atom*); -extern Colormap (*XCopyColormapAndFree_dylibloader_wrapper_xlib)( Display*, Colormap); -extern Colormap (*XCreateColormap_dylibloader_wrapper_xlib)( Display*, Window, Visual*, int); -extern Cursor (*XCreatePixmapCursor_dylibloader_wrapper_xlib)( Display*, Pixmap, Pixmap, XColor*, XColor*, unsigned int, unsigned int); -extern Cursor (*XCreateGlyphCursor_dylibloader_wrapper_xlib)( Display*, Font, Font, unsigned int, unsigned int,const XColor*,const XColor*); -extern Cursor (*XCreateFontCursor_dylibloader_wrapper_xlib)( Display*, unsigned int); -extern Font (*XLoadFont_dylibloader_wrapper_xlib)( Display*,const char*); -extern GC (*XCreateGC_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned long, XGCValues*); -extern GContext (*XGContextFromGC_dylibloader_wrapper_xlib)( GC); -extern void (*XFlushGC_dylibloader_wrapper_xlib)( Display*, GC); -extern Pixmap (*XCreatePixmap_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int); -extern Pixmap (*XCreateBitmapFromData_dylibloader_wrapper_xlib)( Display*, Drawable,const char*, unsigned int, unsigned int); -extern Pixmap (*XCreatePixmapFromBitmapData_dylibloader_wrapper_xlib)( Display*, Drawable, char*, unsigned int, unsigned int, unsigned long, unsigned long, unsigned int); -extern Window (*XCreateSimpleWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int, unsigned int, unsigned long, unsigned long); -extern Window (*XGetSelectionOwner_dylibloader_wrapper_xlib)( Display*, Atom); -extern Window (*XCreateWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual*, unsigned long, XSetWindowAttributes*); -extern Colormap* (*XListInstalledColormaps_dylibloader_wrapper_xlib)( Display*, Window, int*); -extern char** (*XListFonts_dylibloader_wrapper_xlib)( Display*,const char*, int, int*); -extern char** (*XListFontsWithInfo_dylibloader_wrapper_xlib)( Display*,const char*, int, int*, XFontStruct**); -extern char** (*XGetFontPath_dylibloader_wrapper_xlib)( Display*, int*); -extern char** (*XListExtensions_dylibloader_wrapper_xlib)( Display*, int*); -extern Atom* (*XListProperties_dylibloader_wrapper_xlib)( Display*, Window, int*); -extern XHostAddress* (*XListHosts_dylibloader_wrapper_xlib)( Display*, int*, int*); -extern KeySym (*XKeycodeToKeysym_dylibloader_wrapper_xlib)( Display*, KeyCode, int); -extern KeySym (*XLookupKeysym_dylibloader_wrapper_xlib)( XKeyEvent*, int); -extern KeySym* (*XGetKeyboardMapping_dylibloader_wrapper_xlib)( Display*, KeyCode, int, int*); -extern KeySym (*XStringToKeysym_dylibloader_wrapper_xlib)(const char*); -extern long (*XMaxRequestSize_dylibloader_wrapper_xlib)( Display*); -extern long (*XExtendedMaxRequestSize_dylibloader_wrapper_xlib)( Display*); -extern char* (*XResourceManagerString_dylibloader_wrapper_xlib)( Display*); -extern char* (*XScreenResourceString_dylibloader_wrapper_xlib)( Screen*); -extern unsigned long (*XDisplayMotionBufferSize_dylibloader_wrapper_xlib)( Display*); -extern VisualID (*XVisualIDFromVisual_dylibloader_wrapper_xlib)( Visual*); -extern int (*XInitThreads_dylibloader_wrapper_xlib)( void); -extern void (*XLockDisplay_dylibloader_wrapper_xlib)( Display*); -extern void (*XUnlockDisplay_dylibloader_wrapper_xlib)( Display*); -extern XExtCodes* (*XInitExtension_dylibloader_wrapper_xlib)( Display*,const char*); -extern XExtCodes* (*XAddExtension_dylibloader_wrapper_xlib)( Display*); -extern XExtData* (*XFindOnExtensionList_dylibloader_wrapper_xlib)( XExtData**, int); -extern XExtData** (*XEHeadOfExtensionList_dylibloader_wrapper_xlib)( XEDataObject); -extern Window (*XRootWindow_dylibloader_wrapper_xlib)( Display*, int); -extern Window (*XDefaultRootWindow_dylibloader_wrapper_xlib)( Display*); -extern Window (*XRootWindowOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern Visual* (*XDefaultVisual_dylibloader_wrapper_xlib)( Display*, int); -extern Visual* (*XDefaultVisualOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern GC (*XDefaultGC_dylibloader_wrapper_xlib)( Display*, int); -extern GC (*XDefaultGCOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern unsigned long (*XBlackPixel_dylibloader_wrapper_xlib)( Display*, int); -extern unsigned long (*XWhitePixel_dylibloader_wrapper_xlib)( Display*, int); -extern unsigned long (*XAllPlanes_dylibloader_wrapper_xlib)( void); -extern unsigned long (*XBlackPixelOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern unsigned long (*XWhitePixelOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern unsigned long (*XNextRequest_dylibloader_wrapper_xlib)( Display*); -extern unsigned long (*XLastKnownRequestProcessed_dylibloader_wrapper_xlib)( Display*); -extern char* (*XServerVendor_dylibloader_wrapper_xlib)( Display*); -extern char* (*XDisplayString_dylibloader_wrapper_xlib)( Display*); -extern Colormap (*XDefaultColormap_dylibloader_wrapper_xlib)( Display*, int); -extern Colormap (*XDefaultColormapOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern Display* (*XDisplayOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern Screen* (*XScreenOfDisplay_dylibloader_wrapper_xlib)( Display*, int); -extern Screen* (*XDefaultScreenOfDisplay_dylibloader_wrapper_xlib)( Display*); -extern long (*XEventMaskOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern int (*XScreenNumberOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern XErrorHandler (*XSetErrorHandler_dylibloader_wrapper_xlib)( XErrorHandler); -extern XIOErrorHandler (*XSetIOErrorHandler_dylibloader_wrapper_xlib)( XIOErrorHandler); -extern XPixmapFormatValues* (*XListPixmapFormats_dylibloader_wrapper_xlib)( Display*, int*); -extern int* (*XListDepths_dylibloader_wrapper_xlib)( Display*, int, int*); -extern int (*XReconfigureWMWindow_dylibloader_wrapper_xlib)( Display*, Window, int, unsigned int, XWindowChanges*); -extern int (*XGetWMProtocols_dylibloader_wrapper_xlib)( Display*, Window, Atom**, int*); -extern int (*XSetWMProtocols_dylibloader_wrapper_xlib)( Display*, Window, Atom*, int); -extern int (*XIconifyWindow_dylibloader_wrapper_xlib)( Display*, Window, int); -extern int (*XWithdrawWindow_dylibloader_wrapper_xlib)( Display*, Window, int); -extern int (*XGetCommand_dylibloader_wrapper_xlib)( Display*, Window, char***, int*); -extern int (*XGetWMColormapWindows_dylibloader_wrapper_xlib)( Display*, Window, Window**, int*); -extern int (*XSetWMColormapWindows_dylibloader_wrapper_xlib)( Display*, Window, Window*, int); -extern void (*XFreeStringList_dylibloader_wrapper_xlib)( char**); -extern int (*XSetTransientForHint_dylibloader_wrapper_xlib)( Display*, Window, Window); -extern int (*XActivateScreenSaver_dylibloader_wrapper_xlib)( Display*); -extern int (*XAddHost_dylibloader_wrapper_xlib)( Display*, XHostAddress*); -extern int (*XAddHosts_dylibloader_wrapper_xlib)( Display*, XHostAddress*, int); -extern int (*XAddToExtensionList_dylibloader_wrapper_xlib)(struct _XExtData**, XExtData*); -extern int (*XAddToSaveSet_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XAllocColor_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*); -extern int (*XAllocColorCells_dylibloader_wrapper_xlib)( Display*, Colormap, int, unsigned long*, unsigned int, unsigned long*, unsigned int); -extern int (*XAllocColorPlanes_dylibloader_wrapper_xlib)( Display*, Colormap, int, unsigned long*, int, int, int, int, unsigned long*, unsigned long*, unsigned long*); -extern int (*XAllocNamedColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, XColor*, XColor*); -extern int (*XAllowEvents_dylibloader_wrapper_xlib)( Display*, int, Time); -extern int (*XAutoRepeatOff_dylibloader_wrapper_xlib)( Display*); -extern int (*XAutoRepeatOn_dylibloader_wrapper_xlib)( Display*); -extern int (*XBell_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XBitmapBitOrder_dylibloader_wrapper_xlib)( Display*); -extern int (*XBitmapPad_dylibloader_wrapper_xlib)( Display*); -extern int (*XBitmapUnit_dylibloader_wrapper_xlib)( Display*); -extern int (*XCellsOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern int (*XChangeActivePointerGrab_dylibloader_wrapper_xlib)( Display*, unsigned int, Cursor, Time); -extern int (*XChangeGC_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, XGCValues*); -extern int (*XChangeKeyboardControl_dylibloader_wrapper_xlib)( Display*, unsigned long, XKeyboardControl*); -extern int (*XChangeKeyboardMapping_dylibloader_wrapper_xlib)( Display*, int, int, KeySym*, int); -extern int (*XChangePointerControl_dylibloader_wrapper_xlib)( Display*, int, int, int, int, int); -extern int (*XChangeProperty_dylibloader_wrapper_xlib)( Display*, Window, Atom, Atom, int, int,const unsigned char*, int); -extern int (*XChangeSaveSet_dylibloader_wrapper_xlib)( Display*, Window, int); -extern int (*XChangeWindowAttributes_dylibloader_wrapper_xlib)( Display*, Window, unsigned long, XSetWindowAttributes*); -extern int (*XCheckIfEvent_dylibloader_wrapper_xlib)( Display*, XEvent*, Bool (*) (Display*, XEvent*, XPointer), XPointer); -extern int (*XCheckMaskEvent_dylibloader_wrapper_xlib)( Display*, long, XEvent*); -extern int (*XCheckTypedEvent_dylibloader_wrapper_xlib)( Display*, int, XEvent*); -extern int (*XCheckTypedWindowEvent_dylibloader_wrapper_xlib)( Display*, Window, int, XEvent*); -extern int (*XCheckWindowEvent_dylibloader_wrapper_xlib)( Display*, Window, long, XEvent*); -extern int (*XCirculateSubwindows_dylibloader_wrapper_xlib)( Display*, Window, int); -extern int (*XCirculateSubwindowsDown_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XCirculateSubwindowsUp_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XClearArea_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int, int); -extern int (*XClearWindow_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XCloseDisplay_dylibloader_wrapper_xlib)( Display*); -extern int (*XConfigureWindow_dylibloader_wrapper_xlib)( Display*, Window, unsigned int, XWindowChanges*); -extern int (*XConnectionNumber_dylibloader_wrapper_xlib)( Display*); -extern int (*XConvertSelection_dylibloader_wrapper_xlib)( Display*, Atom, Atom, Atom, Window, Time); -extern int (*XCopyArea_dylibloader_wrapper_xlib)( Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int); -extern int (*XCopyGC_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, GC); -extern int (*XCopyPlane_dylibloader_wrapper_xlib)( Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int, unsigned long); -extern int (*XDefaultDepth_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XDefaultDepthOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern int (*XDefaultScreen_dylibloader_wrapper_xlib)( Display*); -extern int (*XDefineCursor_dylibloader_wrapper_xlib)( Display*, Window, Cursor); -extern int (*XDeleteProperty_dylibloader_wrapper_xlib)( Display*, Window, Atom); -extern int (*XDestroyWindow_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XDestroySubwindows_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XDoesBackingStore_dylibloader_wrapper_xlib)( Screen*); -extern int (*XDoesSaveUnders_dylibloader_wrapper_xlib)( Screen*); -extern int (*XDisableAccessControl_dylibloader_wrapper_xlib)( Display*); -extern int (*XDisplayCells_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XDisplayHeight_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XDisplayHeightMM_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XDisplayKeycodes_dylibloader_wrapper_xlib)( Display*, int*, int*); -extern int (*XDisplayPlanes_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XDisplayWidth_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XDisplayWidthMM_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XDrawArc_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int, int, int); -extern int (*XDrawArcs_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XArc*, int); -extern int (*XDrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const char*, int); -extern int (*XDrawImageString16_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const XChar2b*, int); -extern int (*XDrawLine_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, int, int); -extern int (*XDrawLines_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XPoint*, int, int); -extern int (*XDrawPoint_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int); -extern int (*XDrawPoints_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XPoint*, int, int); -extern int (*XDrawRectangle_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int); -extern int (*XDrawRectangles_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XRectangle*, int); -extern int (*XDrawSegments_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XSegment*, int); -extern int (*XDrawString_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const char*, int); -extern int (*XDrawString16_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int,const XChar2b*, int); -extern int (*XDrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XTextItem*, int); -extern int (*XDrawText16_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XTextItem16*, int); -extern int (*XEnableAccessControl_dylibloader_wrapper_xlib)( Display*); -extern int (*XEventsQueued_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XFetchName_dylibloader_wrapper_xlib)( Display*, Window, char**); -extern int (*XFillArc_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int, int, int); -extern int (*XFillArcs_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XArc*, int); -extern int (*XFillPolygon_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XPoint*, int, int, int); -extern int (*XFillRectangle_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, unsigned int, unsigned int); -extern int (*XFillRectangles_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XRectangle*, int); -extern int (*XFlush_dylibloader_wrapper_xlib)( Display*); -extern int (*XForceScreenSaver_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XFree_dylibloader_wrapper_xlib)( void*); -extern int (*XFreeColormap_dylibloader_wrapper_xlib)( Display*, Colormap); -extern int (*XFreeColors_dylibloader_wrapper_xlib)( Display*, Colormap, unsigned long*, int, unsigned long); -extern int (*XFreeCursor_dylibloader_wrapper_xlib)( Display*, Cursor); -extern int (*XFreeExtensionList_dylibloader_wrapper_xlib)( char**); -extern int (*XFreeFont_dylibloader_wrapper_xlib)( Display*, XFontStruct*); -extern int (*XFreeFontInfo_dylibloader_wrapper_xlib)( char**, XFontStruct*, int); -extern int (*XFreeFontNames_dylibloader_wrapper_xlib)( char**); -extern int (*XFreeFontPath_dylibloader_wrapper_xlib)( char**); -extern int (*XFreeGC_dylibloader_wrapper_xlib)( Display*, GC); -extern int (*XFreeModifiermap_dylibloader_wrapper_xlib)( XModifierKeymap*); -extern int (*XFreePixmap_dylibloader_wrapper_xlib)( Display*, Pixmap); -extern int (*XGeometry_dylibloader_wrapper_xlib)( Display*, int,const char*,const char*, unsigned int, unsigned int, unsigned int, int, int, int*, int*, int*, int*); -extern int (*XGetErrorDatabaseText_dylibloader_wrapper_xlib)( Display*,const char*,const char*,const char*, char*, int); -extern int (*XGetErrorText_dylibloader_wrapper_xlib)( Display*, int, char*, int); -extern int (*XGetFontProperty_dylibloader_wrapper_xlib)( XFontStruct*, Atom, unsigned long*); -extern int (*XGetGCValues_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, XGCValues*); -extern int (*XGetGeometry_dylibloader_wrapper_xlib)( Display*, Drawable, Window*, int*, int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*); -extern int (*XGetIconName_dylibloader_wrapper_xlib)( Display*, Window, char**); -extern int (*XGetInputFocus_dylibloader_wrapper_xlib)( Display*, Window*, int*); -extern int (*XGetKeyboardControl_dylibloader_wrapper_xlib)( Display*, XKeyboardState*); -extern int (*XGetPointerControl_dylibloader_wrapper_xlib)( Display*, int*, int*, int*); -extern int (*XGetPointerMapping_dylibloader_wrapper_xlib)( Display*, unsigned char*, int); -extern int (*XGetScreenSaver_dylibloader_wrapper_xlib)( Display*, int*, int*, int*, int*); -extern int (*XGetTransientForHint_dylibloader_wrapper_xlib)( Display*, Window, Window*); -extern int (*XGetWindowProperty_dylibloader_wrapper_xlib)( Display*, Window, Atom, long, long, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); -extern int (*XGetWindowAttributes_dylibloader_wrapper_xlib)( Display*, Window, XWindowAttributes*); -extern int (*XGrabButton_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, Window, int, unsigned int, int, int, Window, Cursor); -extern int (*XGrabKey_dylibloader_wrapper_xlib)( Display*, int, unsigned int, Window, int, int, int); -extern int (*XGrabKeyboard_dylibloader_wrapper_xlib)( Display*, Window, int, int, int, Time); -extern int (*XGrabPointer_dylibloader_wrapper_xlib)( Display*, Window, int, unsigned int, int, int, Window, Cursor, Time); -extern int (*XGrabServer_dylibloader_wrapper_xlib)( Display*); -extern int (*XHeightMMOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern int (*XHeightOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern int (*XIfEvent_dylibloader_wrapper_xlib)( Display*, XEvent*, Bool (*) (Display*, XEvent*, XPointer), XPointer); -extern int (*XImageByteOrder_dylibloader_wrapper_xlib)( Display*); -extern int (*XInstallColormap_dylibloader_wrapper_xlib)( Display*, Colormap); -extern KeyCode (*XKeysymToKeycode_dylibloader_wrapper_xlib)( Display*, KeySym); -extern int (*XKillClient_dylibloader_wrapper_xlib)( Display*, XID); -extern int (*XLookupColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, XColor*, XColor*); -extern int (*XLowerWindow_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XMapRaised_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XMapSubwindows_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XMapWindow_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XMaskEvent_dylibloader_wrapper_xlib)( Display*, long, XEvent*); -extern int (*XMaxCmapsOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern int (*XMinCmapsOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern int (*XMoveResizeWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int, unsigned int, unsigned int); -extern int (*XMoveWindow_dylibloader_wrapper_xlib)( Display*, Window, int, int); -extern int (*XNextEvent_dylibloader_wrapper_xlib)( Display*, XEvent*); -extern int (*XNoOp_dylibloader_wrapper_xlib)( Display*); -extern int (*XParseColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, XColor*); -extern int (*XParseGeometry_dylibloader_wrapper_xlib)(const char*, int*, int*, unsigned int*, unsigned int*); -extern int (*XPeekEvent_dylibloader_wrapper_xlib)( Display*, XEvent*); -extern int (*XPeekIfEvent_dylibloader_wrapper_xlib)( Display*, XEvent*, Bool (*) (Display*, XEvent*, XPointer), XPointer); -extern int (*XPending_dylibloader_wrapper_xlib)( Display*); -extern int (*XPlanesOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern int (*XProtocolRevision_dylibloader_wrapper_xlib)( Display*); -extern int (*XProtocolVersion_dylibloader_wrapper_xlib)( Display*); -extern int (*XPutBackEvent_dylibloader_wrapper_xlib)( Display*, XEvent*); -extern int (*XPutImage_dylibloader_wrapper_xlib)( Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int); -extern int (*XQLength_dylibloader_wrapper_xlib)( Display*); -extern int (*XQueryBestCursor_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); -extern int (*XQueryBestSize_dylibloader_wrapper_xlib)( Display*, int, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); -extern int (*XQueryBestStipple_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); -extern int (*XQueryBestTile_dylibloader_wrapper_xlib)( Display*, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*); -extern int (*XQueryColor_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*); -extern int (*XQueryColors_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*, int); -extern int (*XQueryExtension_dylibloader_wrapper_xlib)( Display*,const char*, int*, int*, int*); -extern int (*XQueryKeymap_dylibloader_wrapper_xlib)( Display*, char [32]); -extern int (*XQueryPointer_dylibloader_wrapper_xlib)( Display*, Window, Window*, Window*, int*, int*, int*, int*, unsigned int*); -extern int (*XQueryTextExtents_dylibloader_wrapper_xlib)( Display*, XID,const char*, int, int*, int*, int*, XCharStruct*); -extern int (*XQueryTextExtents16_dylibloader_wrapper_xlib)( Display*, XID,const XChar2b*, int, int*, int*, int*, XCharStruct*); -extern int (*XQueryTree_dylibloader_wrapper_xlib)( Display*, Window, Window*, Window*, Window**, unsigned int*); -extern int (*XRaiseWindow_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XReadBitmapFile_dylibloader_wrapper_xlib)( Display*, Drawable,const char*, unsigned int*, unsigned int*, Pixmap*, int*, int*); -extern int (*XReadBitmapFileData_dylibloader_wrapper_xlib)(const char*, unsigned int*, unsigned int*, unsigned char**, int*, int*); -extern int (*XRebindKeysym_dylibloader_wrapper_xlib)( Display*, KeySym, KeySym*, int,const unsigned char*, int); -extern int (*XRecolorCursor_dylibloader_wrapper_xlib)( Display*, Cursor, XColor*, XColor*); -extern int (*XRefreshKeyboardMapping_dylibloader_wrapper_xlib)( XMappingEvent*); -extern int (*XRemoveFromSaveSet_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XRemoveHost_dylibloader_wrapper_xlib)( Display*, XHostAddress*); -extern int (*XRemoveHosts_dylibloader_wrapper_xlib)( Display*, XHostAddress*, int); -extern int (*XReparentWindow_dylibloader_wrapper_xlib)( Display*, Window, Window, int, int); -extern int (*XResetScreenSaver_dylibloader_wrapper_xlib)( Display*); -extern int (*XResizeWindow_dylibloader_wrapper_xlib)( Display*, Window, unsigned int, unsigned int); -extern int (*XRestackWindows_dylibloader_wrapper_xlib)( Display*, Window*, int); -extern int (*XRotateBuffers_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XRotateWindowProperties_dylibloader_wrapper_xlib)( Display*, Window, Atom*, int, int); -extern int (*XScreenCount_dylibloader_wrapper_xlib)( Display*); -extern int (*XSelectInput_dylibloader_wrapper_xlib)( Display*, Window, long); -extern int (*XSendEvent_dylibloader_wrapper_xlib)( Display*, Window, int, long, XEvent*); -extern int (*XSetAccessControl_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XSetArcMode_dylibloader_wrapper_xlib)( Display*, GC, int); -extern int (*XSetBackground_dylibloader_wrapper_xlib)( Display*, GC, unsigned long); -extern int (*XSetClipMask_dylibloader_wrapper_xlib)( Display*, GC, Pixmap); -extern int (*XSetClipOrigin_dylibloader_wrapper_xlib)( Display*, GC, int, int); -extern int (*XSetClipRectangles_dylibloader_wrapper_xlib)( Display*, GC, int, int, XRectangle*, int, int); -extern int (*XSetCloseDownMode_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XSetCommand_dylibloader_wrapper_xlib)( Display*, Window, char**, int); -extern int (*XSetDashes_dylibloader_wrapper_xlib)( Display*, GC, int,const char*, int); -extern int (*XSetFillRule_dylibloader_wrapper_xlib)( Display*, GC, int); -extern int (*XSetFillStyle_dylibloader_wrapper_xlib)( Display*, GC, int); -extern int (*XSetFont_dylibloader_wrapper_xlib)( Display*, GC, Font); -extern int (*XSetFontPath_dylibloader_wrapper_xlib)( Display*, char**, int); -extern int (*XSetForeground_dylibloader_wrapper_xlib)( Display*, GC, unsigned long); -extern int (*XSetFunction_dylibloader_wrapper_xlib)( Display*, GC, int); -extern int (*XSetGraphicsExposures_dylibloader_wrapper_xlib)( Display*, GC, int); -extern int (*XSetIconName_dylibloader_wrapper_xlib)( Display*, Window,const char*); -extern int (*XSetInputFocus_dylibloader_wrapper_xlib)( Display*, Window, int, Time); -extern int (*XSetLineAttributes_dylibloader_wrapper_xlib)( Display*, GC, unsigned int, int, int, int); -extern int (*XSetModifierMapping_dylibloader_wrapper_xlib)( Display*, XModifierKeymap*); -extern int (*XSetPlaneMask_dylibloader_wrapper_xlib)( Display*, GC, unsigned long); -extern int (*XSetPointerMapping_dylibloader_wrapper_xlib)( Display*,const unsigned char*, int); -extern int (*XSetScreenSaver_dylibloader_wrapper_xlib)( Display*, int, int, int, int); -extern int (*XSetSelectionOwner_dylibloader_wrapper_xlib)( Display*, Atom, Window, Time); -extern int (*XSetState_dylibloader_wrapper_xlib)( Display*, GC, unsigned long, unsigned long, int, unsigned long); -extern int (*XSetStipple_dylibloader_wrapper_xlib)( Display*, GC, Pixmap); -extern int (*XSetSubwindowMode_dylibloader_wrapper_xlib)( Display*, GC, int); -extern int (*XSetTSOrigin_dylibloader_wrapper_xlib)( Display*, GC, int, int); -extern int (*XSetTile_dylibloader_wrapper_xlib)( Display*, GC, Pixmap); -extern int (*XSetWindowBackground_dylibloader_wrapper_xlib)( Display*, Window, unsigned long); -extern int (*XSetWindowBackgroundPixmap_dylibloader_wrapper_xlib)( Display*, Window, Pixmap); -extern int (*XSetWindowBorder_dylibloader_wrapper_xlib)( Display*, Window, unsigned long); -extern int (*XSetWindowBorderPixmap_dylibloader_wrapper_xlib)( Display*, Window, Pixmap); -extern int (*XSetWindowBorderWidth_dylibloader_wrapper_xlib)( Display*, Window, unsigned int); -extern int (*XSetWindowColormap_dylibloader_wrapper_xlib)( Display*, Window, Colormap); -extern int (*XStoreBuffer_dylibloader_wrapper_xlib)( Display*,const char*, int, int); -extern int (*XStoreBytes_dylibloader_wrapper_xlib)( Display*,const char*, int); -extern int (*XStoreColor_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*); -extern int (*XStoreColors_dylibloader_wrapper_xlib)( Display*, Colormap, XColor*, int); -extern int (*XStoreName_dylibloader_wrapper_xlib)( Display*, Window,const char*); -extern int (*XStoreNamedColor_dylibloader_wrapper_xlib)( Display*, Colormap,const char*, unsigned long, int); -extern int (*XSync_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XTextExtents_dylibloader_wrapper_xlib)( XFontStruct*,const char*, int, int*, int*, int*, XCharStruct*); -extern int (*XTextExtents16_dylibloader_wrapper_xlib)( XFontStruct*,const XChar2b*, int, int*, int*, int*, XCharStruct*); -extern int (*XTextWidth_dylibloader_wrapper_xlib)( XFontStruct*,const char*, int); -extern int (*XTextWidth16_dylibloader_wrapper_xlib)( XFontStruct*,const XChar2b*, int); -extern int (*XTranslateCoordinates_dylibloader_wrapper_xlib)( Display*, Window, Window, int, int, int*, int*, Window*); -extern int (*XUndefineCursor_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XUngrabButton_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, Window); -extern int (*XUngrabKey_dylibloader_wrapper_xlib)( Display*, int, unsigned int, Window); -extern int (*XUngrabKeyboard_dylibloader_wrapper_xlib)( Display*, Time); -extern int (*XUngrabPointer_dylibloader_wrapper_xlib)( Display*, Time); -extern int (*XUngrabServer_dylibloader_wrapper_xlib)( Display*); -extern int (*XUninstallColormap_dylibloader_wrapper_xlib)( Display*, Colormap); -extern int (*XUnloadFont_dylibloader_wrapper_xlib)( Display*, Font); -extern int (*XUnmapSubwindows_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XUnmapWindow_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XVendorRelease_dylibloader_wrapper_xlib)( Display*); -extern int (*XWarpPointer_dylibloader_wrapper_xlib)( Display*, Window, Window, int, int, unsigned int, unsigned int, int, int); -extern int (*XWidthMMOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern int (*XWidthOfScreen_dylibloader_wrapper_xlib)( Screen*); -extern int (*XWindowEvent_dylibloader_wrapper_xlib)( Display*, Window, long, XEvent*); -extern int (*XWriteBitmapFile_dylibloader_wrapper_xlib)( Display*,const char*, Pixmap, unsigned int, unsigned int, int, int); -extern int (*XSupportsLocale_dylibloader_wrapper_xlib)( void); -extern char* (*XSetLocaleModifiers_dylibloader_wrapper_xlib)(const char*); -extern XOM (*XOpenOM_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*,const char*,const char*); -extern int (*XCloseOM_dylibloader_wrapper_xlib)( XOM); -extern char* (*XSetOMValues_dylibloader_wrapper_xlib)( XOM,...); -extern char* (*XGetOMValues_dylibloader_wrapper_xlib)( XOM,...); -extern Display* (*XDisplayOfOM_dylibloader_wrapper_xlib)( XOM); -extern char* (*XLocaleOfOM_dylibloader_wrapper_xlib)( XOM); -extern XOC (*XCreateOC_dylibloader_wrapper_xlib)( XOM,...); -extern void (*XDestroyOC_dylibloader_wrapper_xlib)( XOC); -extern XOM (*XOMOfOC_dylibloader_wrapper_xlib)( XOC); -extern char* (*XSetOCValues_dylibloader_wrapper_xlib)( XOC,...); -extern char* (*XGetOCValues_dylibloader_wrapper_xlib)( XOC,...); -extern XFontSet (*XCreateFontSet_dylibloader_wrapper_xlib)( Display*,const char*, char***, int*, char**); -extern void (*XFreeFontSet_dylibloader_wrapper_xlib)( Display*, XFontSet); -extern int (*XFontsOfFontSet_dylibloader_wrapper_xlib)( XFontSet, XFontStruct***, char***); -extern char* (*XBaseFontNameListOfFontSet_dylibloader_wrapper_xlib)( XFontSet); -extern char* (*XLocaleOfFontSet_dylibloader_wrapper_xlib)( XFontSet); -extern int (*XContextDependentDrawing_dylibloader_wrapper_xlib)( XFontSet); -extern int (*XDirectionalDependentDrawing_dylibloader_wrapper_xlib)( XFontSet); -extern int (*XContextualDrawing_dylibloader_wrapper_xlib)( XFontSet); -extern XFontSetExtents* (*XExtentsOfFontSet_dylibloader_wrapper_xlib)( XFontSet); -extern int (*XmbTextEscapement_dylibloader_wrapper_xlib)( XFontSet,const char*, int); -extern int (*XwcTextEscapement_dylibloader_wrapper_xlib)( XFontSet,const wchar_t*, int); -extern int (*Xutf8TextEscapement_dylibloader_wrapper_xlib)( XFontSet,const char*, int); -extern int (*XmbTextExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*); -extern int (*XwcTextExtents_dylibloader_wrapper_xlib)( XFontSet,const wchar_t*, int, XRectangle*, XRectangle*); -extern int (*Xutf8TextExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*); -extern int (*XmbTextPerCharExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*, int, int*, XRectangle*, XRectangle*); -extern int (*XwcTextPerCharExtents_dylibloader_wrapper_xlib)( XFontSet,const wchar_t*, int, XRectangle*, XRectangle*, int, int*, XRectangle*, XRectangle*); -extern int (*Xutf8TextPerCharExtents_dylibloader_wrapper_xlib)( XFontSet,const char*, int, XRectangle*, XRectangle*, int, int*, XRectangle*, XRectangle*); -extern void (*XmbDrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XmbTextItem*, int); -extern void (*XwcDrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XwcTextItem*, int); -extern void (*Xutf8DrawText_dylibloader_wrapper_xlib)( Display*, Drawable, GC, int, int, XmbTextItem*, int); -extern void (*XmbDrawString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); -extern void (*XwcDrawString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const wchar_t*, int); -extern void (*Xutf8DrawString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); -extern void (*XmbDrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); -extern void (*XwcDrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const wchar_t*, int); -extern void (*Xutf8DrawImageString_dylibloader_wrapper_xlib)( Display*, Drawable, XFontSet, GC, int, int,const char*, int); -extern XIM (*XOpenIM_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*, char*, char*); -extern int (*XCloseIM_dylibloader_wrapper_xlib)( XIM); -extern char* (*XGetIMValues_dylibloader_wrapper_xlib)( XIM,...); -extern char* (*XSetIMValues_dylibloader_wrapper_xlib)( XIM,...); -extern Display* (*XDisplayOfIM_dylibloader_wrapper_xlib)( XIM); -extern char* (*XLocaleOfIM_dylibloader_wrapper_xlib)( XIM); -extern XIC (*XCreateIC_dylibloader_wrapper_xlib)( XIM,...); -extern void (*XDestroyIC_dylibloader_wrapper_xlib)( XIC); -extern void (*XSetICFocus_dylibloader_wrapper_xlib)( XIC); -extern void (*XUnsetICFocus_dylibloader_wrapper_xlib)( XIC); -extern wchar_t* (*XwcResetIC_dylibloader_wrapper_xlib)( XIC); -extern char* (*XmbResetIC_dylibloader_wrapper_xlib)( XIC); -extern char* (*Xutf8ResetIC_dylibloader_wrapper_xlib)( XIC); -extern char* (*XSetICValues_dylibloader_wrapper_xlib)( XIC,...); -extern char* (*XGetICValues_dylibloader_wrapper_xlib)( XIC,...); -extern XIM (*XIMOfIC_dylibloader_wrapper_xlib)( XIC); -extern int (*XFilterEvent_dylibloader_wrapper_xlib)( XEvent*, Window); -extern int (*XmbLookupString_dylibloader_wrapper_xlib)( XIC, XKeyPressedEvent*, char*, int, KeySym*, int*); -extern int (*XwcLookupString_dylibloader_wrapper_xlib)( XIC, XKeyPressedEvent*, wchar_t*, int, KeySym*, int*); -extern int (*Xutf8LookupString_dylibloader_wrapper_xlib)( XIC, XKeyPressedEvent*, char*, int, KeySym*, int*); -extern XVaNestedList (*XVaCreateNestedList_dylibloader_wrapper_xlib)( int,...); -extern int (*XRegisterIMInstantiateCallback_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*, char*, char*, XIDProc, XPointer); -extern int (*XUnregisterIMInstantiateCallback_dylibloader_wrapper_xlib)( Display*,struct _XrmHashBucketRec*, char*, char*, XIDProc, XPointer); -extern int (*XInternalConnectionNumbers_dylibloader_wrapper_xlib)( Display*, int**, int*); -extern void (*XProcessInternalConnection_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XAddConnectionWatch_dylibloader_wrapper_xlib)( Display*, XConnectionWatchProc, XPointer); -extern void (*XRemoveConnectionWatch_dylibloader_wrapper_xlib)( Display*, XConnectionWatchProc, XPointer); -extern void (*XSetAuthorization_dylibloader_wrapper_xlib)( char*, int, char*, int); -extern int (*_Xmbtowc_dylibloader_wrapper_xlib)( wchar_t*, char*, int); -extern int (*_Xwctomb_dylibloader_wrapper_xlib)( char*, wchar_t); -extern int (*XGetEventData_dylibloader_wrapper_xlib)( Display*, XGenericEventCookie*); -extern void (*XFreeEventData_dylibloader_wrapper_xlib)( Display*, XGenericEventCookie*); -extern XClassHint* (*XAllocClassHint_dylibloader_wrapper_xlib)( void); -extern XIconSize* (*XAllocIconSize_dylibloader_wrapper_xlib)( void); -extern XSizeHints* (*XAllocSizeHints_dylibloader_wrapper_xlib)( void); -extern XStandardColormap* (*XAllocStandardColormap_dylibloader_wrapper_xlib)( void); -extern XWMHints* (*XAllocWMHints_dylibloader_wrapper_xlib)( void); -extern int (*XClipBox_dylibloader_wrapper_xlib)( Region, XRectangle*); -extern Region (*XCreateRegion_dylibloader_wrapper_xlib)( void); -extern const char* (*XDefaultString_dylibloader_wrapper_xlib)( void); -extern int (*XDeleteContext_dylibloader_wrapper_xlib)( Display*, XID, XContext); -extern int (*XDestroyRegion_dylibloader_wrapper_xlib)( Region); -extern int (*XEmptyRegion_dylibloader_wrapper_xlib)( Region); -extern int (*XEqualRegion_dylibloader_wrapper_xlib)( Region, Region); -extern int (*XFindContext_dylibloader_wrapper_xlib)( Display*, XID, XContext, XPointer*); -extern int (*XGetClassHint_dylibloader_wrapper_xlib)( Display*, Window, XClassHint*); -extern int (*XGetIconSizes_dylibloader_wrapper_xlib)( Display*, Window, XIconSize**, int*); -extern int (*XGetNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); -extern int (*XGetRGBColormaps_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap**, int*, Atom); -extern int (*XGetSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, Atom); -extern int (*XGetStandardColormap_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap*, Atom); -extern int (*XGetTextProperty_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*, Atom); -extern XVisualInfo* (*XGetVisualInfo_dylibloader_wrapper_xlib)( Display*, long, XVisualInfo*, int*); -extern int (*XGetWMClientMachine_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); -extern XWMHints* (*XGetWMHints_dylibloader_wrapper_xlib)( Display*, Window); -extern int (*XGetWMIconName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); -extern int (*XGetWMName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); -extern int (*XGetWMNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, long*); -extern int (*XGetWMSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, long*, Atom); -extern int (*XGetZoomHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); -extern int (*XIntersectRegion_dylibloader_wrapper_xlib)( Region, Region, Region); -extern void (*XConvertCase_dylibloader_wrapper_xlib)( KeySym, KeySym*, KeySym*); -extern int (*XLookupString_dylibloader_wrapper_xlib)( XKeyEvent*, char*, int, KeySym*, XComposeStatus*); -extern int (*XMatchVisualInfo_dylibloader_wrapper_xlib)( Display*, int, int, int, XVisualInfo*); -extern int (*XOffsetRegion_dylibloader_wrapper_xlib)( Region, int, int); -extern int (*XPointInRegion_dylibloader_wrapper_xlib)( Region, int, int); -extern Region (*XPolygonRegion_dylibloader_wrapper_xlib)( XPoint*, int, int); -extern int (*XRectInRegion_dylibloader_wrapper_xlib)( Region, int, int, unsigned int, unsigned int); -extern int (*XSaveContext_dylibloader_wrapper_xlib)( Display*, XID, XContext,const char*); -extern int (*XSetClassHint_dylibloader_wrapper_xlib)( Display*, Window, XClassHint*); -extern int (*XSetIconSizes_dylibloader_wrapper_xlib)( Display*, Window, XIconSize*, int); -extern int (*XSetNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); -extern void (*XSetRGBColormaps_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap*, int, Atom); -extern int (*XSetSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, Atom); -extern int (*XSetStandardProperties_dylibloader_wrapper_xlib)( Display*, Window,const char*,const char*, Pixmap, char**, int, XSizeHints*); -extern void (*XSetTextProperty_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*, Atom); -extern void (*XSetWMClientMachine_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); -extern int (*XSetWMHints_dylibloader_wrapper_xlib)( Display*, Window, XWMHints*); -extern void (*XSetWMIconName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); -extern void (*XSetWMName_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*); -extern void (*XSetWMNormalHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); -extern void (*XSetWMProperties_dylibloader_wrapper_xlib)( Display*, Window, XTextProperty*, XTextProperty*, char**, int, XSizeHints*, XWMHints*, XClassHint*); -extern void (*XmbSetWMProperties_dylibloader_wrapper_xlib)( Display*, Window,const char*,const char*, char**, int, XSizeHints*, XWMHints*, XClassHint*); -extern void (*Xutf8SetWMProperties_dylibloader_wrapper_xlib)( Display*, Window,const char*,const char*, char**, int, XSizeHints*, XWMHints*, XClassHint*); -extern void (*XSetWMSizeHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*, Atom); -extern int (*XSetRegion_dylibloader_wrapper_xlib)( Display*, GC, Region); -extern void (*XSetStandardColormap_dylibloader_wrapper_xlib)( Display*, Window, XStandardColormap*, Atom); -extern int (*XSetZoomHints_dylibloader_wrapper_xlib)( Display*, Window, XSizeHints*); -extern int (*XShrinkRegion_dylibloader_wrapper_xlib)( Region, int, int); -extern int (*XStringListToTextProperty_dylibloader_wrapper_xlib)( char**, int, XTextProperty*); -extern int (*XSubtractRegion_dylibloader_wrapper_xlib)( Region, Region, Region); -extern int (*XmbTextListToTextProperty_dylibloader_wrapper_xlib)( Display*, char**, int, XICCEncodingStyle, XTextProperty*); -extern int (*XwcTextListToTextProperty_dylibloader_wrapper_xlib)( Display*, wchar_t**, int, XICCEncodingStyle, XTextProperty*); -extern int (*Xutf8TextListToTextProperty_dylibloader_wrapper_xlib)( Display*, char**, int, XICCEncodingStyle, XTextProperty*); -extern void (*XwcFreeStringList_dylibloader_wrapper_xlib)( wchar_t**); -extern int (*XTextPropertyToStringList_dylibloader_wrapper_xlib)( XTextProperty*, char***, int*); -extern int (*XmbTextPropertyToTextList_dylibloader_wrapper_xlib)( Display*,const XTextProperty*, char***, int*); -extern int (*XwcTextPropertyToTextList_dylibloader_wrapper_xlib)( Display*,const XTextProperty*, wchar_t***, int*); -extern int (*Xutf8TextPropertyToTextList_dylibloader_wrapper_xlib)( Display*,const XTextProperty*, char***, int*); -extern int (*XUnionRectWithRegion_dylibloader_wrapper_xlib)( XRectangle*, Region, Region); -extern int (*XUnionRegion_dylibloader_wrapper_xlib)( Region, Region, Region); -extern int (*XWMGeometry_dylibloader_wrapper_xlib)( Display*, int,const char*,const char*, unsigned int, XSizeHints*, int*, int*, int*, int*, int*); -extern int (*XXorRegion_dylibloader_wrapper_xlib)( Region, Region, Region); -extern int (*XkbIgnoreExtension_dylibloader_wrapper_xlib)( int); -extern Display* (*XkbOpenDisplay_dylibloader_wrapper_xlib)( char*, int*, int*, int*, int*, int*); -extern int (*XkbQueryExtension_dylibloader_wrapper_xlib)( Display*, int*, int*, int*, int*, int*); -extern int (*XkbUseExtension_dylibloader_wrapper_xlib)( Display*, int*, int*); -extern int (*XkbLibraryVersion_dylibloader_wrapper_xlib)( int*, int*); -extern unsigned int (*XkbSetXlibControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); -extern unsigned int (*XkbGetXlibControls_dylibloader_wrapper_xlib)( Display*); -extern unsigned int (*XkbXlibControlsImplemented_dylibloader_wrapper_xlib)( void); -extern void (*XkbSetAtomFuncs_dylibloader_wrapper_xlib)( XkbInternAtomFunc, XkbGetAtomNameFunc); -extern KeySym (*XkbKeycodeToKeysym_dylibloader_wrapper_xlib)( Display*, KeyCode, int, int); -extern unsigned int (*XkbKeysymToModifiers_dylibloader_wrapper_xlib)( Display*, KeySym); -extern int (*XkbLookupKeySym_dylibloader_wrapper_xlib)( Display*, KeyCode, unsigned int, unsigned int*, KeySym*); -extern int (*XkbLookupKeyBinding_dylibloader_wrapper_xlib)( Display*, KeySym, unsigned int, char*, int, int*); -extern int (*XkbTranslateKeyCode_dylibloader_wrapper_xlib)( XkbDescPtr, KeyCode, unsigned int, unsigned int*, KeySym*); -extern int (*XkbTranslateKeySym_dylibloader_wrapper_xlib)( Display*, KeySym*, unsigned int, char*, int, int*); -extern int (*XkbSetAutoRepeatRate_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); -extern int (*XkbGetAutoRepeatRate_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*, unsigned int*); -extern int (*XkbChangeEnabledControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); -extern int (*XkbDeviceBell_dylibloader_wrapper_xlib)( Display*, Window, int, int, int, int, Atom); -extern int (*XkbForceDeviceBell_dylibloader_wrapper_xlib)( Display*, int, int, int, int); -extern int (*XkbDeviceBellEvent_dylibloader_wrapper_xlib)( Display*, Window, int, int, int, int, Atom); -extern int (*XkbBell_dylibloader_wrapper_xlib)( Display*, Window, int, Atom); -extern int (*XkbForceBell_dylibloader_wrapper_xlib)( Display*, int); -extern int (*XkbBellEvent_dylibloader_wrapper_xlib)( Display*, Window, int, Atom); -extern int (*XkbSelectEvents_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); -extern int (*XkbSelectEventDetails_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned long, unsigned long); -extern void (*XkbNoteMapChanges_dylibloader_wrapper_xlib)( XkbMapChangesPtr, XkbMapNotifyEvent*, unsigned int); -extern void (*XkbNoteNameChanges_dylibloader_wrapper_xlib)( XkbNameChangesPtr, XkbNamesNotifyEvent*, unsigned int); -extern int (*XkbGetIndicatorState_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*); -extern int (*XkbGetIndicatorMap_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); -extern int (*XkbSetIndicatorMap_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); -extern int (*XkbGetNamedIndicator_dylibloader_wrapper_xlib)( Display*, Atom, int*, int*, XkbIndicatorMapPtr, int*); -extern int (*XkbGetNamedDeviceIndicator_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, Atom, int*, int*, XkbIndicatorMapPtr, int*); -extern int (*XkbSetNamedIndicator_dylibloader_wrapper_xlib)( Display*, Atom, int, int, int, XkbIndicatorMapPtr); -extern int (*XkbSetNamedDeviceIndicator_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, Atom, int, int, int, XkbIndicatorMapPtr); -extern int (*XkbLockModifiers_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); -extern int (*XkbLatchModifiers_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int); -extern int (*XkbLockGroup_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); -extern int (*XkbLatchGroup_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); -extern int (*XkbSetServerInternalMods_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); -extern int (*XkbSetIgnoreLockMods_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); -extern int (*XkbVirtualModsToReal_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int*); -extern int (*XkbComputeEffectiveMap_dylibloader_wrapper_xlib)( XkbDescPtr, XkbKeyTypePtr, unsigned char*); -extern int (*XkbInitCanonicalKeyTypes_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); -extern XkbDescPtr (*XkbAllocKeyboard_dylibloader_wrapper_xlib)( void); -extern void (*XkbFreeKeyboard_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); -extern int (*XkbAllocClientMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int); -extern int (*XkbAllocServerMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int); -extern void (*XkbFreeClientMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); -extern void (*XkbFreeServerMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); -extern XkbKeyTypePtr (*XkbAddKeyType_dylibloader_wrapper_xlib)( XkbDescPtr, Atom, int, int, int); -extern int (*XkbAllocIndicatorMaps_dylibloader_wrapper_xlib)( XkbDescPtr); -extern void (*XkbFreeIndicatorMaps_dylibloader_wrapper_xlib)( XkbDescPtr); -extern XkbDescPtr (*XkbGetMap_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); -extern int (*XkbGetUpdatedMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); -extern int (*XkbGetMapChanges_dylibloader_wrapper_xlib)( Display*, XkbDescPtr, XkbMapChangesPtr); -extern int (*XkbRefreshKeyboardMapping_dylibloader_wrapper_xlib)( XkbMapNotifyEvent*); -extern int (*XkbGetKeyTypes_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); -extern int (*XkbGetKeySyms_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); -extern int (*XkbGetKeyActions_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); -extern int (*XkbGetKeyBehaviors_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); -extern int (*XkbGetVirtualMods_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); -extern int (*XkbGetKeyExplicitComponents_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); -extern int (*XkbGetKeyModifierMap_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); -extern int (*XkbGetKeyVirtualModMap_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, XkbDescPtr); -extern int (*XkbAllocControls_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int); -extern void (*XkbFreeControls_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); -extern int (*XkbGetControls_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); -extern int (*XkbSetControls_dylibloader_wrapper_xlib)( Display*, unsigned long, XkbDescPtr); -extern void (*XkbNoteControlsChanges_dylibloader_wrapper_xlib)( XkbControlsChangesPtr, XkbControlsNotifyEvent*, unsigned int); -extern int (*XkbAllocCompatMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, unsigned int); -extern void (*XkbFreeCompatMap_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); -extern int (*XkbGetCompatMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); -extern int (*XkbSetCompatMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr, int); -extern int (*XkbAllocNames_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int, int); -extern int (*XkbGetNames_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); -extern int (*XkbSetNames_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, XkbDescPtr); -extern int (*XkbChangeNames_dylibloader_wrapper_xlib)( Display*, XkbDescPtr, XkbNameChangesPtr); -extern void (*XkbFreeNames_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, int); -extern int (*XkbGetState_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbStatePtr); -extern int (*XkbSetMap_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDescPtr); -extern int (*XkbChangeMap_dylibloader_wrapper_xlib)( Display*, XkbDescPtr, XkbMapChangesPtr); -extern int (*XkbSetDetectableAutoRepeat_dylibloader_wrapper_xlib)( Display*, int, int*); -extern int (*XkbGetDetectableAutoRepeat_dylibloader_wrapper_xlib)( Display*, int*); -extern int (*XkbSetAutoResetControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*, unsigned int*); -extern int (*XkbGetAutoResetControls_dylibloader_wrapper_xlib)( Display*, unsigned int*, unsigned int*); -extern int (*XkbSetPerClientControls_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int*); -extern int (*XkbGetPerClientControls_dylibloader_wrapper_xlib)( Display*, unsigned int*); -extern int (*XkbCopyKeyType_dylibloader_wrapper_xlib)( XkbKeyTypePtr, XkbKeyTypePtr); -extern int (*XkbCopyKeyTypes_dylibloader_wrapper_xlib)( XkbKeyTypePtr, XkbKeyTypePtr, int); -extern int (*XkbResizeKeyType_dylibloader_wrapper_xlib)( XkbDescPtr, int, int, int, int); -extern KeySym* (*XkbResizeKeySyms_dylibloader_wrapper_xlib)( XkbDescPtr, int, int); -extern XkbAction* (*XkbResizeKeyActions_dylibloader_wrapper_xlib)( XkbDescPtr, int, int); -extern int (*XkbChangeTypesOfKey_dylibloader_wrapper_xlib)( XkbDescPtr, int, int, unsigned int, int*, XkbMapChangesPtr); -extern int (*XkbChangeKeycodeRange_dylibloader_wrapper_xlib)( XkbDescPtr, int, int, XkbChangesPtr); -extern XkbComponentListPtr (*XkbListComponents_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbComponentNamesPtr, int*); -extern void (*XkbFreeComponentList_dylibloader_wrapper_xlib)( XkbComponentListPtr); -extern XkbDescPtr (*XkbGetKeyboard_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int); -extern XkbDescPtr (*XkbGetKeyboardByName_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbComponentNamesPtr, unsigned int, unsigned int, int); -extern int (*XkbKeyTypesForCoreSymbols_dylibloader_wrapper_xlib)( XkbDescPtr, int, KeySym*, unsigned int, int*, KeySym*); -extern int (*XkbApplyCompatMapToKey_dylibloader_wrapper_xlib)( XkbDescPtr, KeyCode, XkbChangesPtr); -extern int (*XkbUpdateMapFromCore_dylibloader_wrapper_xlib)( XkbDescPtr, KeyCode, int, int, KeySym*, XkbChangesPtr); -extern XkbDeviceLedInfoPtr (*XkbAddDeviceLedInfo_dylibloader_wrapper_xlib)( XkbDeviceInfoPtr, unsigned int, unsigned int); -extern int (*XkbResizeDeviceButtonActions_dylibloader_wrapper_xlib)( XkbDeviceInfoPtr, unsigned int); -extern XkbDeviceInfoPtr (*XkbAllocDeviceInfo_dylibloader_wrapper_xlib)( unsigned int, unsigned int, unsigned int); -extern void (*XkbFreeDeviceInfo_dylibloader_wrapper_xlib)( XkbDeviceInfoPtr, unsigned int, int); -extern void (*XkbNoteDeviceChanges_dylibloader_wrapper_xlib)( XkbDeviceChangesPtr, XkbExtensionDeviceNotifyEvent*, unsigned int); -extern XkbDeviceInfoPtr (*XkbGetDeviceInfo_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, unsigned int, unsigned int); -extern int (*XkbGetDeviceInfoChanges_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, XkbDeviceChangesPtr); -extern int (*XkbGetDeviceButtonActions_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, int, unsigned int, unsigned int); -extern int (*XkbGetDeviceLedInfo_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, unsigned int, unsigned int, unsigned int); -extern int (*XkbSetDeviceInfo_dylibloader_wrapper_xlib)( Display*, unsigned int, XkbDeviceInfoPtr); -extern int (*XkbChangeDeviceInfo_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, XkbDeviceChangesPtr); -extern int (*XkbSetDeviceLedInfo_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, unsigned int, unsigned int, unsigned int); -extern int (*XkbSetDeviceButtonActions_dylibloader_wrapper_xlib)( Display*, XkbDeviceInfoPtr, unsigned int, unsigned int); -extern char (*XkbToControl_dylibloader_wrapper_xlib)( char); -extern int (*XkbSetDebuggingFlags_dylibloader_wrapper_xlib)( Display*, unsigned int, unsigned int, char*, unsigned int, unsigned int, unsigned int*, unsigned int*); -extern int (*XkbApplyVirtualModChanges_dylibloader_wrapper_xlib)( XkbDescPtr, unsigned int, XkbChangesPtr); -extern int (*XkbUpdateActionVirtualMods_dylibloader_wrapper_xlib)( XkbDescPtr, XkbAction*, unsigned int); -extern void (*XkbUpdateKeyTypeVirtualMods_dylibloader_wrapper_xlib)( XkbDescPtr, XkbKeyTypePtr, unsigned int, XkbChangesPtr); +extern int (*_Xmblen_dylibloader_wrapper_xlib)(char *, int); +extern XFontStruct *(*XLoadQueryFont_dylibloader_wrapper_xlib)(Display *, const char *); +extern XFontStruct *(*XQueryFont_dylibloader_wrapper_xlib)(Display *, XID); +extern XTimeCoord *(*XGetMotionEvents_dylibloader_wrapper_xlib)(Display *, Window, Time, Time, int *); +extern XModifierKeymap *(*XDeleteModifiermapEntry_dylibloader_wrapper_xlib)(XModifierKeymap *, KeyCode, int); +extern XModifierKeymap *(*XGetModifierMapping_dylibloader_wrapper_xlib)(Display *); +extern XModifierKeymap *(*XInsertModifiermapEntry_dylibloader_wrapper_xlib)(XModifierKeymap *, KeyCode, int); +extern XModifierKeymap *(*XNewModifiermap_dylibloader_wrapper_xlib)(int); +extern XImage *(*XCreateImage_dylibloader_wrapper_xlib)(Display *, Visual *, unsigned int, int, int, char *, unsigned int, unsigned int, int, int); +extern int (*XInitImage_dylibloader_wrapper_xlib)(XImage *); +extern XImage *(*XGetImage_dylibloader_wrapper_xlib)(Display *, Drawable, int, int, unsigned int, unsigned int, unsigned long, int); +extern XImage *(*XGetSubImage_dylibloader_wrapper_xlib)(Display *, Drawable, int, int, unsigned int, unsigned int, unsigned long, int, XImage *, int, int); +extern Display *(*XOpenDisplay_dylibloader_wrapper_xlib)(const char *); +extern void (*XrmInitialize_dylibloader_wrapper_xlib)(void); +extern char *(*XFetchBytes_dylibloader_wrapper_xlib)(Display *, int *); +extern char *(*XFetchBuffer_dylibloader_wrapper_xlib)(Display *, int *, int); +extern char *(*XGetAtomName_dylibloader_wrapper_xlib)(Display *, Atom); +extern int (*XGetAtomNames_dylibloader_wrapper_xlib)(Display *, Atom *, int, char **); +extern char *(*XGetDefault_dylibloader_wrapper_xlib)(Display *, const char *, const char *); +extern char *(*XDisplayName_dylibloader_wrapper_xlib)(const char *); +extern char *(*XKeysymToString_dylibloader_wrapper_xlib)(KeySym); +extern int (*(*XSynchronize_dylibloader_wrapper_xlib)(Display *, int))(Display *); +extern int (*(*XSetAfterFunction_dylibloader_wrapper_xlib)(Display *, int (*)(Display *)))(Display *); +extern Atom (*XInternAtom_dylibloader_wrapper_xlib)(Display *, const char *, int); +extern int (*XInternAtoms_dylibloader_wrapper_xlib)(Display *, char **, int, int, Atom *); +extern Colormap (*XCopyColormapAndFree_dylibloader_wrapper_xlib)(Display *, Colormap); +extern Colormap (*XCreateColormap_dylibloader_wrapper_xlib)(Display *, Window, Visual *, int); +extern Cursor (*XCreatePixmapCursor_dylibloader_wrapper_xlib)(Display *, Pixmap, Pixmap, XColor *, XColor *, unsigned int, unsigned int); +extern Cursor (*XCreateGlyphCursor_dylibloader_wrapper_xlib)(Display *, Font, Font, unsigned int, unsigned int, const XColor *, const XColor *); +extern Cursor (*XCreateFontCursor_dylibloader_wrapper_xlib)(Display *, unsigned int); +extern Font (*XLoadFont_dylibloader_wrapper_xlib)(Display *, const char *); +extern GC (*XCreateGC_dylibloader_wrapper_xlib)(Display *, Drawable, unsigned long, XGCValues *); +extern GContext (*XGContextFromGC_dylibloader_wrapper_xlib)(GC); +extern void (*XFlushGC_dylibloader_wrapper_xlib)(Display *, GC); +extern Pixmap (*XCreatePixmap_dylibloader_wrapper_xlib)(Display *, Drawable, unsigned int, unsigned int, unsigned int); +extern Pixmap (*XCreateBitmapFromData_dylibloader_wrapper_xlib)(Display *, Drawable, const char *, unsigned int, unsigned int); +extern Pixmap (*XCreatePixmapFromBitmapData_dylibloader_wrapper_xlib)(Display *, Drawable, char *, unsigned int, unsigned int, unsigned long, unsigned long, unsigned int); +extern Window (*XCreateSimpleWindow_dylibloader_wrapper_xlib)(Display *, Window, int, int, unsigned int, unsigned int, unsigned int, unsigned long, unsigned long); +extern Window (*XGetSelectionOwner_dylibloader_wrapper_xlib)(Display *, Atom); +extern Window (*XCreateWindow_dylibloader_wrapper_xlib)(Display *, Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual *, unsigned long, XSetWindowAttributes *); +extern Colormap *(*XListInstalledColormaps_dylibloader_wrapper_xlib)(Display *, Window, int *); +extern char **(*XListFonts_dylibloader_wrapper_xlib)(Display *, const char *, int, int *); +extern char **(*XListFontsWithInfo_dylibloader_wrapper_xlib)(Display *, const char *, int, int *, XFontStruct **); +extern char **(*XGetFontPath_dylibloader_wrapper_xlib)(Display *, int *); +extern char **(*XListExtensions_dylibloader_wrapper_xlib)(Display *, int *); +extern Atom *(*XListProperties_dylibloader_wrapper_xlib)(Display *, Window, int *); +extern XHostAddress *(*XListHosts_dylibloader_wrapper_xlib)(Display *, int *, int *); +extern KeySym (*XKeycodeToKeysym_dylibloader_wrapper_xlib)(Display *, KeyCode, int); +extern KeySym (*XLookupKeysym_dylibloader_wrapper_xlib)(XKeyEvent *, int); +extern KeySym *(*XGetKeyboardMapping_dylibloader_wrapper_xlib)(Display *, KeyCode, int, int *); +extern KeySym (*XStringToKeysym_dylibloader_wrapper_xlib)(const char *); +extern long (*XMaxRequestSize_dylibloader_wrapper_xlib)(Display *); +extern long (*XExtendedMaxRequestSize_dylibloader_wrapper_xlib)(Display *); +extern char *(*XResourceManagerString_dylibloader_wrapper_xlib)(Display *); +extern char *(*XScreenResourceString_dylibloader_wrapper_xlib)(Screen *); +extern unsigned long (*XDisplayMotionBufferSize_dylibloader_wrapper_xlib)(Display *); +extern VisualID (*XVisualIDFromVisual_dylibloader_wrapper_xlib)(Visual *); +extern int (*XInitThreads_dylibloader_wrapper_xlib)(void); +extern void (*XLockDisplay_dylibloader_wrapper_xlib)(Display *); +extern void (*XUnlockDisplay_dylibloader_wrapper_xlib)(Display *); +extern XExtCodes *(*XInitExtension_dylibloader_wrapper_xlib)(Display *, const char *); +extern XExtCodes *(*XAddExtension_dylibloader_wrapper_xlib)(Display *); +extern XExtData *(*XFindOnExtensionList_dylibloader_wrapper_xlib)(XExtData **, int); +extern XExtData **(*XEHeadOfExtensionList_dylibloader_wrapper_xlib)(XEDataObject); +extern Window (*XRootWindow_dylibloader_wrapper_xlib)(Display *, int); +extern Window (*XDefaultRootWindow_dylibloader_wrapper_xlib)(Display *); +extern Window (*XRootWindowOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern Visual *(*XDefaultVisual_dylibloader_wrapper_xlib)(Display *, int); +extern Visual *(*XDefaultVisualOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern GC (*XDefaultGC_dylibloader_wrapper_xlib)(Display *, int); +extern GC (*XDefaultGCOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern unsigned long (*XBlackPixel_dylibloader_wrapper_xlib)(Display *, int); +extern unsigned long (*XWhitePixel_dylibloader_wrapper_xlib)(Display *, int); +extern unsigned long (*XAllPlanes_dylibloader_wrapper_xlib)(void); +extern unsigned long (*XBlackPixelOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern unsigned long (*XWhitePixelOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern unsigned long (*XNextRequest_dylibloader_wrapper_xlib)(Display *); +extern unsigned long (*XLastKnownRequestProcessed_dylibloader_wrapper_xlib)(Display *); +extern char *(*XServerVendor_dylibloader_wrapper_xlib)(Display *); +extern char *(*XDisplayString_dylibloader_wrapper_xlib)(Display *); +extern Colormap (*XDefaultColormap_dylibloader_wrapper_xlib)(Display *, int); +extern Colormap (*XDefaultColormapOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern Display *(*XDisplayOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern Screen *(*XScreenOfDisplay_dylibloader_wrapper_xlib)(Display *, int); +extern Screen *(*XDefaultScreenOfDisplay_dylibloader_wrapper_xlib)(Display *); +extern long (*XEventMaskOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern int (*XScreenNumberOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern XErrorHandler (*XSetErrorHandler_dylibloader_wrapper_xlib)(XErrorHandler); +extern XIOErrorHandler (*XSetIOErrorHandler_dylibloader_wrapper_xlib)(XIOErrorHandler); +extern void (*XSetIOErrorExitHandler_dylibloader_wrapper_xlib)(Display *, XIOErrorExitHandler, void *); +extern XPixmapFormatValues *(*XListPixmapFormats_dylibloader_wrapper_xlib)(Display *, int *); +extern int *(*XListDepths_dylibloader_wrapper_xlib)(Display *, int, int *); +extern int (*XReconfigureWMWindow_dylibloader_wrapper_xlib)(Display *, Window, int, unsigned int, XWindowChanges *); +extern int (*XGetWMProtocols_dylibloader_wrapper_xlib)(Display *, Window, Atom **, int *); +extern int (*XSetWMProtocols_dylibloader_wrapper_xlib)(Display *, Window, Atom *, int); +extern int (*XIconifyWindow_dylibloader_wrapper_xlib)(Display *, Window, int); +extern int (*XWithdrawWindow_dylibloader_wrapper_xlib)(Display *, Window, int); +extern int (*XGetCommand_dylibloader_wrapper_xlib)(Display *, Window, char ***, int *); +extern int (*XGetWMColormapWindows_dylibloader_wrapper_xlib)(Display *, Window, Window **, int *); +extern int (*XSetWMColormapWindows_dylibloader_wrapper_xlib)(Display *, Window, Window *, int); +extern void (*XFreeStringList_dylibloader_wrapper_xlib)(char **); +extern int (*XSetTransientForHint_dylibloader_wrapper_xlib)(Display *, Window, Window); +extern int (*XActivateScreenSaver_dylibloader_wrapper_xlib)(Display *); +extern int (*XAddHost_dylibloader_wrapper_xlib)(Display *, XHostAddress *); +extern int (*XAddHosts_dylibloader_wrapper_xlib)(Display *, XHostAddress *, int); +extern int (*XAddToExtensionList_dylibloader_wrapper_xlib)(struct _XExtData **, XExtData *); +extern int (*XAddToSaveSet_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XAllocColor_dylibloader_wrapper_xlib)(Display *, Colormap, XColor *); +extern int (*XAllocColorCells_dylibloader_wrapper_xlib)(Display *, Colormap, int, unsigned long *, unsigned int, unsigned long *, unsigned int); +extern int (*XAllocColorPlanes_dylibloader_wrapper_xlib)(Display *, Colormap, int, unsigned long *, int, int, int, int, unsigned long *, unsigned long *, unsigned long *); +extern int (*XAllocNamedColor_dylibloader_wrapper_xlib)(Display *, Colormap, const char *, XColor *, XColor *); +extern int (*XAllowEvents_dylibloader_wrapper_xlib)(Display *, int, Time); +extern int (*XAutoRepeatOff_dylibloader_wrapper_xlib)(Display *); +extern int (*XAutoRepeatOn_dylibloader_wrapper_xlib)(Display *); +extern int (*XBell_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XBitmapBitOrder_dylibloader_wrapper_xlib)(Display *); +extern int (*XBitmapPad_dylibloader_wrapper_xlib)(Display *); +extern int (*XBitmapUnit_dylibloader_wrapper_xlib)(Display *); +extern int (*XCellsOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern int (*XChangeActivePointerGrab_dylibloader_wrapper_xlib)(Display *, unsigned int, Cursor, Time); +extern int (*XChangeGC_dylibloader_wrapper_xlib)(Display *, GC, unsigned long, XGCValues *); +extern int (*XChangeKeyboardControl_dylibloader_wrapper_xlib)(Display *, unsigned long, XKeyboardControl *); +extern int (*XChangeKeyboardMapping_dylibloader_wrapper_xlib)(Display *, int, int, KeySym *, int); +extern int (*XChangePointerControl_dylibloader_wrapper_xlib)(Display *, int, int, int, int, int); +extern int (*XChangeProperty_dylibloader_wrapper_xlib)(Display *, Window, Atom, Atom, int, int, const unsigned char *, int); +extern int (*XChangeSaveSet_dylibloader_wrapper_xlib)(Display *, Window, int); +extern int (*XChangeWindowAttributes_dylibloader_wrapper_xlib)(Display *, Window, unsigned long, XSetWindowAttributes *); +extern int (*XCheckIfEvent_dylibloader_wrapper_xlib)(Display *, XEvent *, int (*)(Display *, XEvent *, XPointer), XPointer); +extern int (*XCheckMaskEvent_dylibloader_wrapper_xlib)(Display *, long, XEvent *); +extern int (*XCheckTypedEvent_dylibloader_wrapper_xlib)(Display *, int, XEvent *); +extern int (*XCheckTypedWindowEvent_dylibloader_wrapper_xlib)(Display *, Window, int, XEvent *); +extern int (*XCheckWindowEvent_dylibloader_wrapper_xlib)(Display *, Window, long, XEvent *); +extern int (*XCirculateSubwindows_dylibloader_wrapper_xlib)(Display *, Window, int); +extern int (*XCirculateSubwindowsDown_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XCirculateSubwindowsUp_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XClearArea_dylibloader_wrapper_xlib)(Display *, Window, int, int, unsigned int, unsigned int, int); +extern int (*XClearWindow_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XCloseDisplay_dylibloader_wrapper_xlib)(Display *); +extern int (*XConfigureWindow_dylibloader_wrapper_xlib)(Display *, Window, unsigned int, XWindowChanges *); +extern int (*XConnectionNumber_dylibloader_wrapper_xlib)(Display *); +extern int (*XConvertSelection_dylibloader_wrapper_xlib)(Display *, Atom, Atom, Atom, Window, Time); +extern int (*XCopyArea_dylibloader_wrapper_xlib)(Display *, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int); +extern int (*XCopyGC_dylibloader_wrapper_xlib)(Display *, GC, unsigned long, GC); +extern int (*XCopyPlane_dylibloader_wrapper_xlib)(Display *, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int, unsigned long); +extern int (*XDefaultDepth_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XDefaultDepthOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern int (*XDefaultScreen_dylibloader_wrapper_xlib)(Display *); +extern int (*XDefineCursor_dylibloader_wrapper_xlib)(Display *, Window, Cursor); +extern int (*XDeleteProperty_dylibloader_wrapper_xlib)(Display *, Window, Atom); +extern int (*XDestroyWindow_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XDestroySubwindows_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XDoesBackingStore_dylibloader_wrapper_xlib)(Screen *); +extern int (*XDoesSaveUnders_dylibloader_wrapper_xlib)(Screen *); +extern int (*XDisableAccessControl_dylibloader_wrapper_xlib)(Display *); +extern int (*XDisplayCells_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XDisplayHeight_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XDisplayHeightMM_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XDisplayKeycodes_dylibloader_wrapper_xlib)(Display *, int *, int *); +extern int (*XDisplayPlanes_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XDisplayWidth_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XDisplayWidthMM_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XDrawArc_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, unsigned int, unsigned int, int, int); +extern int (*XDrawArcs_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XArc *, int); +extern int (*XDrawImageString_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, const char *, int); +extern int (*XDrawImageString16_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, const XChar2b *, int); +extern int (*XDrawLine_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, int, int); +extern int (*XDrawLines_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XPoint *, int, int); +extern int (*XDrawPoint_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int); +extern int (*XDrawPoints_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XPoint *, int, int); +extern int (*XDrawRectangle_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, unsigned int, unsigned int); +extern int (*XDrawRectangles_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XRectangle *, int); +extern int (*XDrawSegments_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XSegment *, int); +extern int (*XDrawString_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, const char *, int); +extern int (*XDrawString16_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, const XChar2b *, int); +extern int (*XDrawText_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, XTextItem *, int); +extern int (*XDrawText16_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, XTextItem16 *, int); +extern int (*XEnableAccessControl_dylibloader_wrapper_xlib)(Display *); +extern int (*XEventsQueued_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XFetchName_dylibloader_wrapper_xlib)(Display *, Window, char **); +extern int (*XFillArc_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, unsigned int, unsigned int, int, int); +extern int (*XFillArcs_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XArc *, int); +extern int (*XFillPolygon_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XPoint *, int, int, int); +extern int (*XFillRectangle_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, unsigned int, unsigned int); +extern int (*XFillRectangles_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XRectangle *, int); +extern int (*XFlush_dylibloader_wrapper_xlib)(Display *); +extern int (*XForceScreenSaver_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XFree_dylibloader_wrapper_xlib)(void *); +extern int (*XFreeColormap_dylibloader_wrapper_xlib)(Display *, Colormap); +extern int (*XFreeColors_dylibloader_wrapper_xlib)(Display *, Colormap, unsigned long *, int, unsigned long); +extern int (*XFreeCursor_dylibloader_wrapper_xlib)(Display *, Cursor); +extern int (*XFreeExtensionList_dylibloader_wrapper_xlib)(char **); +extern int (*XFreeFont_dylibloader_wrapper_xlib)(Display *, XFontStruct *); +extern int (*XFreeFontInfo_dylibloader_wrapper_xlib)(char **, XFontStruct *, int); +extern int (*XFreeFontNames_dylibloader_wrapper_xlib)(char **); +extern int (*XFreeFontPath_dylibloader_wrapper_xlib)(char **); +extern int (*XFreeGC_dylibloader_wrapper_xlib)(Display *, GC); +extern int (*XFreeModifiermap_dylibloader_wrapper_xlib)(XModifierKeymap *); +extern int (*XFreePixmap_dylibloader_wrapper_xlib)(Display *, Pixmap); +extern int (*XGeometry_dylibloader_wrapper_xlib)(Display *, int, const char *, const char *, unsigned int, unsigned int, unsigned int, int, int, int *, int *, int *, int *); +extern int (*XGetErrorDatabaseText_dylibloader_wrapper_xlib)(Display *, const char *, const char *, const char *, char *, int); +extern int (*XGetErrorText_dylibloader_wrapper_xlib)(Display *, int, char *, int); +extern int (*XGetFontProperty_dylibloader_wrapper_xlib)(XFontStruct *, Atom, unsigned long *); +extern int (*XGetGCValues_dylibloader_wrapper_xlib)(Display *, GC, unsigned long, XGCValues *); +extern int (*XGetGeometry_dylibloader_wrapper_xlib)(Display *, Drawable, Window *, int *, int *, unsigned int *, unsigned int *, unsigned int *, unsigned int *); +extern int (*XGetIconName_dylibloader_wrapper_xlib)(Display *, Window, char **); +extern int (*XGetInputFocus_dylibloader_wrapper_xlib)(Display *, Window *, int *); +extern int (*XGetKeyboardControl_dylibloader_wrapper_xlib)(Display *, XKeyboardState *); +extern int (*XGetPointerControl_dylibloader_wrapper_xlib)(Display *, int *, int *, int *); +extern int (*XGetPointerMapping_dylibloader_wrapper_xlib)(Display *, unsigned char *, int); +extern int (*XGetScreenSaver_dylibloader_wrapper_xlib)(Display *, int *, int *, int *, int *); +extern int (*XGetTransientForHint_dylibloader_wrapper_xlib)(Display *, Window, Window *); +extern int (*XGetWindowProperty_dylibloader_wrapper_xlib)(Display *, Window, Atom, long, long, int, Atom, Atom *, int *, unsigned long *, unsigned long *, unsigned char **); +extern int (*XGetWindowAttributes_dylibloader_wrapper_xlib)(Display *, Window, XWindowAttributes *); +extern int (*XGrabButton_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, Window, int, unsigned int, int, int, Window, Cursor); +extern int (*XGrabKey_dylibloader_wrapper_xlib)(Display *, int, unsigned int, Window, int, int, int); +extern int (*XGrabKeyboard_dylibloader_wrapper_xlib)(Display *, Window, int, int, int, Time); +extern int (*XGrabPointer_dylibloader_wrapper_xlib)(Display *, Window, int, unsigned int, int, int, Window, Cursor, Time); +extern int (*XGrabServer_dylibloader_wrapper_xlib)(Display *); +extern int (*XHeightMMOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern int (*XHeightOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern int (*XIfEvent_dylibloader_wrapper_xlib)(Display *, XEvent *, int (*)(Display *, XEvent *, XPointer), XPointer); +extern int (*XImageByteOrder_dylibloader_wrapper_xlib)(Display *); +extern int (*XInstallColormap_dylibloader_wrapper_xlib)(Display *, Colormap); +extern KeyCode (*XKeysymToKeycode_dylibloader_wrapper_xlib)(Display *, KeySym); +extern int (*XKillClient_dylibloader_wrapper_xlib)(Display *, XID); +extern int (*XLookupColor_dylibloader_wrapper_xlib)(Display *, Colormap, const char *, XColor *, XColor *); +extern int (*XLowerWindow_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XMapRaised_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XMapSubwindows_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XMapWindow_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XMaskEvent_dylibloader_wrapper_xlib)(Display *, long, XEvent *); +extern int (*XMaxCmapsOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern int (*XMinCmapsOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern int (*XMoveResizeWindow_dylibloader_wrapper_xlib)(Display *, Window, int, int, unsigned int, unsigned int); +extern int (*XMoveWindow_dylibloader_wrapper_xlib)(Display *, Window, int, int); +extern int (*XNextEvent_dylibloader_wrapper_xlib)(Display *, XEvent *); +extern int (*XNoOp_dylibloader_wrapper_xlib)(Display *); +extern int (*XParseColor_dylibloader_wrapper_xlib)(Display *, Colormap, const char *, XColor *); +extern int (*XParseGeometry_dylibloader_wrapper_xlib)(const char *, int *, int *, unsigned int *, unsigned int *); +extern int (*XPeekEvent_dylibloader_wrapper_xlib)(Display *, XEvent *); +extern int (*XPeekIfEvent_dylibloader_wrapper_xlib)(Display *, XEvent *, int (*)(Display *, XEvent *, XPointer), XPointer); +extern int (*XPending_dylibloader_wrapper_xlib)(Display *); +extern int (*XPlanesOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern int (*XProtocolRevision_dylibloader_wrapper_xlib)(Display *); +extern int (*XProtocolVersion_dylibloader_wrapper_xlib)(Display *); +extern int (*XPutBackEvent_dylibloader_wrapper_xlib)(Display *, XEvent *); +extern int (*XPutImage_dylibloader_wrapper_xlib)(Display *, Drawable, GC, XImage *, int, int, int, int, unsigned int, unsigned int); +extern int (*XQLength_dylibloader_wrapper_xlib)(Display *); +extern int (*XQueryBestCursor_dylibloader_wrapper_xlib)(Display *, Drawable, unsigned int, unsigned int, unsigned int *, unsigned int *); +extern int (*XQueryBestSize_dylibloader_wrapper_xlib)(Display *, int, Drawable, unsigned int, unsigned int, unsigned int *, unsigned int *); +extern int (*XQueryBestStipple_dylibloader_wrapper_xlib)(Display *, Drawable, unsigned int, unsigned int, unsigned int *, unsigned int *); +extern int (*XQueryBestTile_dylibloader_wrapper_xlib)(Display *, Drawable, unsigned int, unsigned int, unsigned int *, unsigned int *); +extern int (*XQueryColor_dylibloader_wrapper_xlib)(Display *, Colormap, XColor *); +extern int (*XQueryColors_dylibloader_wrapper_xlib)(Display *, Colormap, XColor *, int); +extern int (*XQueryExtension_dylibloader_wrapper_xlib)(Display *, const char *, int *, int *, int *); +extern int (*XQueryKeymap_dylibloader_wrapper_xlib)(Display *, char [32]); +extern int (*XQueryPointer_dylibloader_wrapper_xlib)(Display *, Window, Window *, Window *, int *, int *, int *, int *, unsigned int *); +extern int (*XQueryTextExtents_dylibloader_wrapper_xlib)(Display *, XID, const char *, int, int *, int *, int *, XCharStruct *); +extern int (*XQueryTextExtents16_dylibloader_wrapper_xlib)(Display *, XID, const XChar2b *, int, int *, int *, int *, XCharStruct *); +extern int (*XQueryTree_dylibloader_wrapper_xlib)(Display *, Window, Window *, Window *, Window **, unsigned int *); +extern int (*XRaiseWindow_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XReadBitmapFile_dylibloader_wrapper_xlib)(Display *, Drawable, const char *, unsigned int *, unsigned int *, Pixmap *, int *, int *); +extern int (*XReadBitmapFileData_dylibloader_wrapper_xlib)(const char *, unsigned int *, unsigned int *, unsigned char **, int *, int *); +extern int (*XRebindKeysym_dylibloader_wrapper_xlib)(Display *, KeySym, KeySym *, int, const unsigned char *, int); +extern int (*XRecolorCursor_dylibloader_wrapper_xlib)(Display *, Cursor, XColor *, XColor *); +extern int (*XRefreshKeyboardMapping_dylibloader_wrapper_xlib)(XMappingEvent *); +extern int (*XRemoveFromSaveSet_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XRemoveHost_dylibloader_wrapper_xlib)(Display *, XHostAddress *); +extern int (*XRemoveHosts_dylibloader_wrapper_xlib)(Display *, XHostAddress *, int); +extern int (*XReparentWindow_dylibloader_wrapper_xlib)(Display *, Window, Window, int, int); +extern int (*XResetScreenSaver_dylibloader_wrapper_xlib)(Display *); +extern int (*XResizeWindow_dylibloader_wrapper_xlib)(Display *, Window, unsigned int, unsigned int); +extern int (*XRestackWindows_dylibloader_wrapper_xlib)(Display *, Window *, int); +extern int (*XRotateBuffers_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XRotateWindowProperties_dylibloader_wrapper_xlib)(Display *, Window, Atom *, int, int); +extern int (*XScreenCount_dylibloader_wrapper_xlib)(Display *); +extern int (*XSelectInput_dylibloader_wrapper_xlib)(Display *, Window, long); +extern int (*XSendEvent_dylibloader_wrapper_xlib)(Display *, Window, int, long, XEvent *); +extern int (*XSetAccessControl_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XSetArcMode_dylibloader_wrapper_xlib)(Display *, GC, int); +extern int (*XSetBackground_dylibloader_wrapper_xlib)(Display *, GC, unsigned long); +extern int (*XSetClipMask_dylibloader_wrapper_xlib)(Display *, GC, Pixmap); +extern int (*XSetClipOrigin_dylibloader_wrapper_xlib)(Display *, GC, int, int); +extern int (*XSetClipRectangles_dylibloader_wrapper_xlib)(Display *, GC, int, int, XRectangle *, int, int); +extern int (*XSetCloseDownMode_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XSetCommand_dylibloader_wrapper_xlib)(Display *, Window, char **, int); +extern int (*XSetDashes_dylibloader_wrapper_xlib)(Display *, GC, int, const char *, int); +extern int (*XSetFillRule_dylibloader_wrapper_xlib)(Display *, GC, int); +extern int (*XSetFillStyle_dylibloader_wrapper_xlib)(Display *, GC, int); +extern int (*XSetFont_dylibloader_wrapper_xlib)(Display *, GC, Font); +extern int (*XSetFontPath_dylibloader_wrapper_xlib)(Display *, char **, int); +extern int (*XSetForeground_dylibloader_wrapper_xlib)(Display *, GC, unsigned long); +extern int (*XSetFunction_dylibloader_wrapper_xlib)(Display *, GC, int); +extern int (*XSetGraphicsExposures_dylibloader_wrapper_xlib)(Display *, GC, int); +extern int (*XSetIconName_dylibloader_wrapper_xlib)(Display *, Window, const char *); +extern int (*XSetInputFocus_dylibloader_wrapper_xlib)(Display *, Window, int, Time); +extern int (*XSetLineAttributes_dylibloader_wrapper_xlib)(Display *, GC, unsigned int, int, int, int); +extern int (*XSetModifierMapping_dylibloader_wrapper_xlib)(Display *, XModifierKeymap *); +extern int (*XSetPlaneMask_dylibloader_wrapper_xlib)(Display *, GC, unsigned long); +extern int (*XSetPointerMapping_dylibloader_wrapper_xlib)(Display *, const unsigned char *, int); +extern int (*XSetScreenSaver_dylibloader_wrapper_xlib)(Display *, int, int, int, int); +extern int (*XSetSelectionOwner_dylibloader_wrapper_xlib)(Display *, Atom, Window, Time); +extern int (*XSetState_dylibloader_wrapper_xlib)(Display *, GC, unsigned long, unsigned long, int, unsigned long); +extern int (*XSetStipple_dylibloader_wrapper_xlib)(Display *, GC, Pixmap); +extern int (*XSetSubwindowMode_dylibloader_wrapper_xlib)(Display *, GC, int); +extern int (*XSetTSOrigin_dylibloader_wrapper_xlib)(Display *, GC, int, int); +extern int (*XSetTile_dylibloader_wrapper_xlib)(Display *, GC, Pixmap); +extern int (*XSetWindowBackground_dylibloader_wrapper_xlib)(Display *, Window, unsigned long); +extern int (*XSetWindowBackgroundPixmap_dylibloader_wrapper_xlib)(Display *, Window, Pixmap); +extern int (*XSetWindowBorder_dylibloader_wrapper_xlib)(Display *, Window, unsigned long); +extern int (*XSetWindowBorderPixmap_dylibloader_wrapper_xlib)(Display *, Window, Pixmap); +extern int (*XSetWindowBorderWidth_dylibloader_wrapper_xlib)(Display *, Window, unsigned int); +extern int (*XSetWindowColormap_dylibloader_wrapper_xlib)(Display *, Window, Colormap); +extern int (*XStoreBuffer_dylibloader_wrapper_xlib)(Display *, const char *, int, int); +extern int (*XStoreBytes_dylibloader_wrapper_xlib)(Display *, const char *, int); +extern int (*XStoreColor_dylibloader_wrapper_xlib)(Display *, Colormap, XColor *); +extern int (*XStoreColors_dylibloader_wrapper_xlib)(Display *, Colormap, XColor *, int); +extern int (*XStoreName_dylibloader_wrapper_xlib)(Display *, Window, const char *); +extern int (*XStoreNamedColor_dylibloader_wrapper_xlib)(Display *, Colormap, const char *, unsigned long, int); +extern int (*XSync_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XTextExtents_dylibloader_wrapper_xlib)(XFontStruct *, const char *, int, int *, int *, int *, XCharStruct *); +extern int (*XTextExtents16_dylibloader_wrapper_xlib)(XFontStruct *, const XChar2b *, int, int *, int *, int *, XCharStruct *); +extern int (*XTextWidth_dylibloader_wrapper_xlib)(XFontStruct *, const char *, int); +extern int (*XTextWidth16_dylibloader_wrapper_xlib)(XFontStruct *, const XChar2b *, int); +extern int (*XTranslateCoordinates_dylibloader_wrapper_xlib)(Display *, Window, Window, int, int, int *, int *, Window *); +extern int (*XUndefineCursor_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XUngrabButton_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, Window); +extern int (*XUngrabKey_dylibloader_wrapper_xlib)(Display *, int, unsigned int, Window); +extern int (*XUngrabKeyboard_dylibloader_wrapper_xlib)(Display *, Time); +extern int (*XUngrabPointer_dylibloader_wrapper_xlib)(Display *, Time); +extern int (*XUngrabServer_dylibloader_wrapper_xlib)(Display *); +extern int (*XUninstallColormap_dylibloader_wrapper_xlib)(Display *, Colormap); +extern int (*XUnloadFont_dylibloader_wrapper_xlib)(Display *, Font); +extern int (*XUnmapSubwindows_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XUnmapWindow_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XVendorRelease_dylibloader_wrapper_xlib)(Display *); +extern int (*XWarpPointer_dylibloader_wrapper_xlib)(Display *, Window, Window, int, int, unsigned int, unsigned int, int, int); +extern int (*XWidthMMOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern int (*XWidthOfScreen_dylibloader_wrapper_xlib)(Screen *); +extern int (*XWindowEvent_dylibloader_wrapper_xlib)(Display *, Window, long, XEvent *); +extern int (*XWriteBitmapFile_dylibloader_wrapper_xlib)(Display *, const char *, Pixmap, unsigned int, unsigned int, int, int); +extern int (*XSupportsLocale_dylibloader_wrapper_xlib)(void); +extern char *(*XSetLocaleModifiers_dylibloader_wrapper_xlib)(const char *); +extern XOM (*XOpenOM_dylibloader_wrapper_xlib)(Display *, struct _XrmHashBucketRec *, const char *, const char *); +extern int (*XCloseOM_dylibloader_wrapper_xlib)(XOM); +extern char *(*XSetOMValues_dylibloader_wrapper_xlib)(XOM, ...); +extern char *(*XGetOMValues_dylibloader_wrapper_xlib)(XOM, ...); +extern Display *(*XDisplayOfOM_dylibloader_wrapper_xlib)(XOM); +extern char *(*XLocaleOfOM_dylibloader_wrapper_xlib)(XOM); +extern XOC (*XCreateOC_dylibloader_wrapper_xlib)(XOM, ...); +extern void (*XDestroyOC_dylibloader_wrapper_xlib)(XOC); +extern XOM (*XOMOfOC_dylibloader_wrapper_xlib)(XOC); +extern char *(*XSetOCValues_dylibloader_wrapper_xlib)(XOC, ...); +extern char *(*XGetOCValues_dylibloader_wrapper_xlib)(XOC, ...); +extern XFontSet (*XCreateFontSet_dylibloader_wrapper_xlib)(Display *, const char *, char ***, int *, char **); +extern void (*XFreeFontSet_dylibloader_wrapper_xlib)(Display *, XFontSet); +extern int (*XFontsOfFontSet_dylibloader_wrapper_xlib)(XFontSet, XFontStruct ***, char ***); +extern char *(*XBaseFontNameListOfFontSet_dylibloader_wrapper_xlib)(XFontSet); +extern char *(*XLocaleOfFontSet_dylibloader_wrapper_xlib)(XFontSet); +extern int (*XContextDependentDrawing_dylibloader_wrapper_xlib)(XFontSet); +extern int (*XDirectionalDependentDrawing_dylibloader_wrapper_xlib)(XFontSet); +extern int (*XContextualDrawing_dylibloader_wrapper_xlib)(XFontSet); +extern XFontSetExtents *(*XExtentsOfFontSet_dylibloader_wrapper_xlib)(XFontSet); +extern int (*XmbTextEscapement_dylibloader_wrapper_xlib)(XFontSet, const char *, int); +extern int (*XwcTextEscapement_dylibloader_wrapper_xlib)(XFontSet, const wchar_t *, int); +extern int (*Xutf8TextEscapement_dylibloader_wrapper_xlib)(XFontSet, const char *, int); +extern int (*XmbTextExtents_dylibloader_wrapper_xlib)(XFontSet, const char *, int, XRectangle *, XRectangle *); +extern int (*XwcTextExtents_dylibloader_wrapper_xlib)(XFontSet, const wchar_t *, int, XRectangle *, XRectangle *); +extern int (*Xutf8TextExtents_dylibloader_wrapper_xlib)(XFontSet, const char *, int, XRectangle *, XRectangle *); +extern int (*XmbTextPerCharExtents_dylibloader_wrapper_xlib)(XFontSet, const char *, int, XRectangle *, XRectangle *, int, int *, XRectangle *, XRectangle *); +extern int (*XwcTextPerCharExtents_dylibloader_wrapper_xlib)(XFontSet, const wchar_t *, int, XRectangle *, XRectangle *, int, int *, XRectangle *, XRectangle *); +extern int (*Xutf8TextPerCharExtents_dylibloader_wrapper_xlib)(XFontSet, const char *, int, XRectangle *, XRectangle *, int, int *, XRectangle *, XRectangle *); +extern void (*XmbDrawText_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, XmbTextItem *, int); +extern void (*XwcDrawText_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, XwcTextItem *, int); +extern void (*Xutf8DrawText_dylibloader_wrapper_xlib)(Display *, Drawable, GC, int, int, XmbTextItem *, int); +extern void (*XmbDrawString_dylibloader_wrapper_xlib)(Display *, Drawable, XFontSet, GC, int, int, const char *, int); +extern void (*XwcDrawString_dylibloader_wrapper_xlib)(Display *, Drawable, XFontSet, GC, int, int, const wchar_t *, int); +extern void (*Xutf8DrawString_dylibloader_wrapper_xlib)(Display *, Drawable, XFontSet, GC, int, int, const char *, int); +extern void (*XmbDrawImageString_dylibloader_wrapper_xlib)(Display *, Drawable, XFontSet, GC, int, int, const char *, int); +extern void (*XwcDrawImageString_dylibloader_wrapper_xlib)(Display *, Drawable, XFontSet, GC, int, int, const wchar_t *, int); +extern void (*Xutf8DrawImageString_dylibloader_wrapper_xlib)(Display *, Drawable, XFontSet, GC, int, int, const char *, int); +extern XIM (*XOpenIM_dylibloader_wrapper_xlib)(Display *, struct _XrmHashBucketRec *, char *, char *); +extern int (*XCloseIM_dylibloader_wrapper_xlib)(XIM); +extern char *(*XGetIMValues_dylibloader_wrapper_xlib)(XIM, ...); +extern char *(*XSetIMValues_dylibloader_wrapper_xlib)(XIM, ...); +extern Display *(*XDisplayOfIM_dylibloader_wrapper_xlib)(XIM); +extern char *(*XLocaleOfIM_dylibloader_wrapper_xlib)(XIM); +extern XIC (*XCreateIC_dylibloader_wrapper_xlib)(XIM, ...); +extern void (*XDestroyIC_dylibloader_wrapper_xlib)(XIC); +extern void (*XSetICFocus_dylibloader_wrapper_xlib)(XIC); +extern void (*XUnsetICFocus_dylibloader_wrapper_xlib)(XIC); +extern wchar_t *(*XwcResetIC_dylibloader_wrapper_xlib)(XIC); +extern char *(*XmbResetIC_dylibloader_wrapper_xlib)(XIC); +extern char *(*Xutf8ResetIC_dylibloader_wrapper_xlib)(XIC); +extern char *(*XSetICValues_dylibloader_wrapper_xlib)(XIC, ...); +extern char *(*XGetICValues_dylibloader_wrapper_xlib)(XIC, ...); +extern XIM (*XIMOfIC_dylibloader_wrapper_xlib)(XIC); +extern int (*XFilterEvent_dylibloader_wrapper_xlib)(XEvent *, Window); +extern int (*XmbLookupString_dylibloader_wrapper_xlib)(XIC, XKeyPressedEvent *, char *, int, KeySym *, int *); +extern int (*XwcLookupString_dylibloader_wrapper_xlib)(XIC, XKeyPressedEvent *, wchar_t *, int, KeySym *, int *); +extern int (*Xutf8LookupString_dylibloader_wrapper_xlib)(XIC, XKeyPressedEvent *, char *, int, KeySym *, int *); +extern XVaNestedList (*XVaCreateNestedList_dylibloader_wrapper_xlib)(int, ...); +extern int (*XRegisterIMInstantiateCallback_dylibloader_wrapper_xlib)(Display *, struct _XrmHashBucketRec *, char *, char *, XIDProc, XPointer); +extern int (*XUnregisterIMInstantiateCallback_dylibloader_wrapper_xlib)(Display *, struct _XrmHashBucketRec *, char *, char *, XIDProc, XPointer); +extern int (*XInternalConnectionNumbers_dylibloader_wrapper_xlib)(Display *, int **, int *); +extern void (*XProcessInternalConnection_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XAddConnectionWatch_dylibloader_wrapper_xlib)(Display *, XConnectionWatchProc, XPointer); +extern void (*XRemoveConnectionWatch_dylibloader_wrapper_xlib)(Display *, XConnectionWatchProc, XPointer); +extern void (*XSetAuthorization_dylibloader_wrapper_xlib)(char *, int, char *, int); +extern int (*_Xmbtowc_dylibloader_wrapper_xlib)(wchar_t *, char *, int); +extern int (*_Xwctomb_dylibloader_wrapper_xlib)(char *, wchar_t); +extern int (*XGetEventData_dylibloader_wrapper_xlib)(Display *, XGenericEventCookie *); +extern void (*XFreeEventData_dylibloader_wrapper_xlib)(Display *, XGenericEventCookie *); +extern int (*XFreeThreads_dylibloader_wrapper_xlib)(void); +extern XClassHint *(*XAllocClassHint_dylibloader_wrapper_xlib)(void); +extern XIconSize *(*XAllocIconSize_dylibloader_wrapper_xlib)(void); +extern XSizeHints *(*XAllocSizeHints_dylibloader_wrapper_xlib)(void); +extern XStandardColormap *(*XAllocStandardColormap_dylibloader_wrapper_xlib)(void); +extern XWMHints *(*XAllocWMHints_dylibloader_wrapper_xlib)(void); +extern int (*XClipBox_dylibloader_wrapper_xlib)(Region, XRectangle *); +extern Region (*XCreateRegion_dylibloader_wrapper_xlib)(void); +extern const char *(*XDefaultString_dylibloader_wrapper_xlib)(void); +extern int (*XDeleteContext_dylibloader_wrapper_xlib)(Display *, XID, XContext); +extern int (*XDestroyRegion_dylibloader_wrapper_xlib)(Region); +extern int (*XEmptyRegion_dylibloader_wrapper_xlib)(Region); +extern int (*XEqualRegion_dylibloader_wrapper_xlib)(Region, Region); +extern int (*XFindContext_dylibloader_wrapper_xlib)(Display *, XID, XContext, XPointer *); +extern int (*XGetClassHint_dylibloader_wrapper_xlib)(Display *, Window, XClassHint *); +extern int (*XGetIconSizes_dylibloader_wrapper_xlib)(Display *, Window, XIconSize **, int *); +extern int (*XGetNormalHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *); +extern int (*XGetRGBColormaps_dylibloader_wrapper_xlib)(Display *, Window, XStandardColormap **, int *, Atom); +extern int (*XGetSizeHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *, Atom); +extern int (*XGetStandardColormap_dylibloader_wrapper_xlib)(Display *, Window, XStandardColormap *, Atom); +extern int (*XGetTextProperty_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *, Atom); +extern XVisualInfo *(*XGetVisualInfo_dylibloader_wrapper_xlib)(Display *, long, XVisualInfo *, int *); +extern int (*XGetWMClientMachine_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *); +extern XWMHints *(*XGetWMHints_dylibloader_wrapper_xlib)(Display *, Window); +extern int (*XGetWMIconName_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *); +extern int (*XGetWMName_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *); +extern int (*XGetWMNormalHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *, long *); +extern int (*XGetWMSizeHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *, long *, Atom); +extern int (*XGetZoomHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *); +extern int (*XIntersectRegion_dylibloader_wrapper_xlib)(Region, Region, Region); +extern void (*XConvertCase_dylibloader_wrapper_xlib)(KeySym, KeySym *, KeySym *); +extern int (*XLookupString_dylibloader_wrapper_xlib)(XKeyEvent *, char *, int, KeySym *, XComposeStatus *); +extern int (*XMatchVisualInfo_dylibloader_wrapper_xlib)(Display *, int, int, int, XVisualInfo *); +extern int (*XOffsetRegion_dylibloader_wrapper_xlib)(Region, int, int); +extern int (*XPointInRegion_dylibloader_wrapper_xlib)(Region, int, int); +extern Region (*XPolygonRegion_dylibloader_wrapper_xlib)(XPoint *, int, int); +extern int (*XRectInRegion_dylibloader_wrapper_xlib)(Region, int, int, unsigned int, unsigned int); +extern int (*XSaveContext_dylibloader_wrapper_xlib)(Display *, XID, XContext, const char *); +extern int (*XSetClassHint_dylibloader_wrapper_xlib)(Display *, Window, XClassHint *); +extern int (*XSetIconSizes_dylibloader_wrapper_xlib)(Display *, Window, XIconSize *, int); +extern int (*XSetNormalHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *); +extern void (*XSetRGBColormaps_dylibloader_wrapper_xlib)(Display *, Window, XStandardColormap *, int, Atom); +extern int (*XSetSizeHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *, Atom); +extern int (*XSetStandardProperties_dylibloader_wrapper_xlib)(Display *, Window, const char *, const char *, Pixmap, char **, int, XSizeHints *); +extern void (*XSetTextProperty_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *, Atom); +extern void (*XSetWMClientMachine_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *); +extern int (*XSetWMHints_dylibloader_wrapper_xlib)(Display *, Window, XWMHints *); +extern void (*XSetWMIconName_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *); +extern void (*XSetWMName_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *); +extern void (*XSetWMNormalHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *); +extern void (*XSetWMProperties_dylibloader_wrapper_xlib)(Display *, Window, XTextProperty *, XTextProperty *, char **, int, XSizeHints *, XWMHints *, XClassHint *); +extern void (*XmbSetWMProperties_dylibloader_wrapper_xlib)(Display *, Window, const char *, const char *, char **, int, XSizeHints *, XWMHints *, XClassHint *); +extern void (*Xutf8SetWMProperties_dylibloader_wrapper_xlib)(Display *, Window, const char *, const char *, char **, int, XSizeHints *, XWMHints *, XClassHint *); +extern void (*XSetWMSizeHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *, Atom); +extern int (*XSetRegion_dylibloader_wrapper_xlib)(Display *, GC, Region); +extern void (*XSetStandardColormap_dylibloader_wrapper_xlib)(Display *, Window, XStandardColormap *, Atom); +extern int (*XSetZoomHints_dylibloader_wrapper_xlib)(Display *, Window, XSizeHints *); +extern int (*XShrinkRegion_dylibloader_wrapper_xlib)(Region, int, int); +extern int (*XStringListToTextProperty_dylibloader_wrapper_xlib)(char **, int, XTextProperty *); +extern int (*XSubtractRegion_dylibloader_wrapper_xlib)(Region, Region, Region); +extern int (*XmbTextListToTextProperty_dylibloader_wrapper_xlib)(Display *, char **, int, XICCEncodingStyle, XTextProperty *); +extern int (*XwcTextListToTextProperty_dylibloader_wrapper_xlib)(Display *, wchar_t **, int, XICCEncodingStyle, XTextProperty *); +extern int (*Xutf8TextListToTextProperty_dylibloader_wrapper_xlib)(Display *, char **, int, XICCEncodingStyle, XTextProperty *); +extern void (*XwcFreeStringList_dylibloader_wrapper_xlib)(wchar_t **); +extern int (*XTextPropertyToStringList_dylibloader_wrapper_xlib)(XTextProperty *, char ***, int *); +extern int (*XmbTextPropertyToTextList_dylibloader_wrapper_xlib)(Display *, const XTextProperty *, char ***, int *); +extern int (*XwcTextPropertyToTextList_dylibloader_wrapper_xlib)(Display *, const XTextProperty *, wchar_t ***, int *); +extern int (*Xutf8TextPropertyToTextList_dylibloader_wrapper_xlib)(Display *, const XTextProperty *, char ***, int *); +extern int (*XUnionRectWithRegion_dylibloader_wrapper_xlib)(XRectangle *, Region, Region); +extern int (*XUnionRegion_dylibloader_wrapper_xlib)(Region, Region, Region); +extern int (*XWMGeometry_dylibloader_wrapper_xlib)(Display *, int, const char *, const char *, unsigned int, XSizeHints *, int *, int *, int *, int *, int *); +extern int (*XXorRegion_dylibloader_wrapper_xlib)(Region, Region, Region); +extern int (*XkbIgnoreExtension_dylibloader_wrapper_xlib)(int); +extern Display *(*XkbOpenDisplay_dylibloader_wrapper_xlib)(char *, int *, int *, int *, int *, int *); +extern int (*XkbQueryExtension_dylibloader_wrapper_xlib)(Display *, int *, int *, int *, int *, int *); +extern int (*XkbUseExtension_dylibloader_wrapper_xlib)(Display *, int *, int *); +extern int (*XkbLibraryVersion_dylibloader_wrapper_xlib)(int *, int *); +extern unsigned int (*XkbSetXlibControls_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int); +extern unsigned int (*XkbGetXlibControls_dylibloader_wrapper_xlib)(Display *); +extern unsigned int (*XkbXlibControlsImplemented_dylibloader_wrapper_xlib)(void); +extern void (*XkbSetAtomFuncs_dylibloader_wrapper_xlib)(XkbInternAtomFunc, XkbGetAtomNameFunc); +extern KeySym (*XkbKeycodeToKeysym_dylibloader_wrapper_xlib)(Display *, KeyCode, int, int); +extern unsigned int (*XkbKeysymToModifiers_dylibloader_wrapper_xlib)(Display *, KeySym); +extern int (*XkbLookupKeySym_dylibloader_wrapper_xlib)(Display *, KeyCode, unsigned int, unsigned int *, KeySym *); +extern int (*XkbLookupKeyBinding_dylibloader_wrapper_xlib)(Display *, KeySym, unsigned int, char *, int, int *); +extern int (*XkbTranslateKeyCode_dylibloader_wrapper_xlib)(XkbDescPtr, KeyCode, unsigned int, unsigned int *, KeySym *); +extern int (*XkbTranslateKeySym_dylibloader_wrapper_xlib)(Display *, KeySym *, unsigned int, char *, int, int *); +extern int (*XkbSetAutoRepeatRate_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int); +extern int (*XkbGetAutoRepeatRate_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int *, unsigned int *); +extern int (*XkbChangeEnabledControls_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int); +extern int (*XkbDeviceBell_dylibloader_wrapper_xlib)(Display *, Window, int, int, int, int, Atom); +extern int (*XkbForceDeviceBell_dylibloader_wrapper_xlib)(Display *, int, int, int, int); +extern int (*XkbDeviceBellEvent_dylibloader_wrapper_xlib)(Display *, Window, int, int, int, int, Atom); +extern int (*XkbBell_dylibloader_wrapper_xlib)(Display *, Window, int, Atom); +extern int (*XkbForceBell_dylibloader_wrapper_xlib)(Display *, int); +extern int (*XkbBellEvent_dylibloader_wrapper_xlib)(Display *, Window, int, Atom); +extern int (*XkbSelectEvents_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int); +extern int (*XkbSelectEventDetails_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned long, unsigned long); +extern void (*XkbNoteMapChanges_dylibloader_wrapper_xlib)(XkbMapChangesPtr, XkbMapNotifyEvent *, unsigned int); +extern void (*XkbNoteNameChanges_dylibloader_wrapper_xlib)(XkbNameChangesPtr, XkbNamesNotifyEvent *, unsigned int); +extern int (*XkbGetIndicatorState_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int *); +extern int (*XkbGetIndicatorMap_dylibloader_wrapper_xlib)(Display *, unsigned long, XkbDescPtr); +extern int (*XkbSetIndicatorMap_dylibloader_wrapper_xlib)(Display *, unsigned long, XkbDescPtr); +extern int (*XkbGetNamedIndicator_dylibloader_wrapper_xlib)(Display *, Atom, int *, int *, XkbIndicatorMapPtr, int *); +extern int (*XkbGetNamedDeviceIndicator_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int, Atom, int *, int *, XkbIndicatorMapPtr, int *); +extern int (*XkbSetNamedIndicator_dylibloader_wrapper_xlib)(Display *, Atom, int, int, int, XkbIndicatorMapPtr); +extern int (*XkbSetNamedDeviceIndicator_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int, Atom, int, int, int, XkbIndicatorMapPtr); +extern int (*XkbLockModifiers_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int); +extern int (*XkbLatchModifiers_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int); +extern int (*XkbLockGroup_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int); +extern int (*XkbLatchGroup_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int); +extern int (*XkbSetServerInternalMods_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); +extern int (*XkbSetIgnoreLockMods_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); +extern int (*XkbVirtualModsToReal_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, unsigned int *); +extern int (*XkbComputeEffectiveMap_dylibloader_wrapper_xlib)(XkbDescPtr, XkbKeyTypePtr, unsigned char *); +extern int (*XkbInitCanonicalKeyTypes_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int); +extern XkbDescPtr (*XkbAllocKeyboard_dylibloader_wrapper_xlib)(void); +extern void (*XkbFreeKeyboard_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int); +extern int (*XkbAllocClientMap_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, unsigned int); +extern int (*XkbAllocServerMap_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, unsigned int); +extern void (*XkbFreeClientMap_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int); +extern void (*XkbFreeServerMap_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int); +extern XkbKeyTypePtr (*XkbAddKeyType_dylibloader_wrapper_xlib)(XkbDescPtr, Atom, int, int, int); +extern int (*XkbAllocIndicatorMaps_dylibloader_wrapper_xlib)(XkbDescPtr); +extern void (*XkbFreeIndicatorMaps_dylibloader_wrapper_xlib)(XkbDescPtr); +extern XkbDescPtr (*XkbGetMap_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int); +extern int (*XkbGetUpdatedMap_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbDescPtr); +extern int (*XkbGetMapChanges_dylibloader_wrapper_xlib)(Display *, XkbDescPtr, XkbMapChangesPtr); +extern int (*XkbRefreshKeyboardMapping_dylibloader_wrapper_xlib)(XkbMapNotifyEvent *); +extern int (*XkbGetKeyTypes_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbGetKeySyms_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbGetKeyActions_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbGetKeyBehaviors_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbGetVirtualMods_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbDescPtr); +extern int (*XkbGetKeyExplicitComponents_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbGetKeyModifierMap_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbGetKeyVirtualModMap_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbAllocControls_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int); +extern void (*XkbFreeControls_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int); +extern int (*XkbGetControls_dylibloader_wrapper_xlib)(Display *, unsigned long, XkbDescPtr); +extern int (*XkbSetControls_dylibloader_wrapper_xlib)(Display *, unsigned long, XkbDescPtr); +extern void (*XkbNoteControlsChanges_dylibloader_wrapper_xlib)(XkbControlsChangesPtr, XkbControlsNotifyEvent *, unsigned int); +extern int (*XkbAllocCompatMap_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, unsigned int); +extern void (*XkbFreeCompatMap_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int); +extern int (*XkbGetCompatMap_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbDescPtr); +extern int (*XkbSetCompatMap_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbDescPtr, int); +extern int (*XkbAllocNames_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int, int); +extern int (*XkbGetNames_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbDescPtr); +extern int (*XkbSetNames_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int, XkbDescPtr); +extern int (*XkbChangeNames_dylibloader_wrapper_xlib)(Display *, XkbDescPtr, XkbNameChangesPtr); +extern void (*XkbFreeNames_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, int); +extern int (*XkbGetState_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbStatePtr); +extern int (*XkbSetMap_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbDescPtr); +extern int (*XkbChangeMap_dylibloader_wrapper_xlib)(Display *, XkbDescPtr, XkbMapChangesPtr); +extern int (*XkbSetDetectableAutoRepeat_dylibloader_wrapper_xlib)(Display *, int, int *); +extern int (*XkbGetDetectableAutoRepeat_dylibloader_wrapper_xlib)(Display *, int *); +extern int (*XkbSetAutoResetControls_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int *, unsigned int *); +extern int (*XkbGetAutoResetControls_dylibloader_wrapper_xlib)(Display *, unsigned int *, unsigned int *); +extern int (*XkbSetPerClientControls_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int *); +extern int (*XkbGetPerClientControls_dylibloader_wrapper_xlib)(Display *, unsigned int *); +extern int (*XkbCopyKeyType_dylibloader_wrapper_xlib)(XkbKeyTypePtr, XkbKeyTypePtr); +extern int (*XkbCopyKeyTypes_dylibloader_wrapper_xlib)(XkbKeyTypePtr, XkbKeyTypePtr, int); +extern int (*XkbResizeKeyType_dylibloader_wrapper_xlib)(XkbDescPtr, int, int, int, int); +extern KeySym *(*XkbResizeKeySyms_dylibloader_wrapper_xlib)(XkbDescPtr, int, int); +extern XkbAction *(*XkbResizeKeyActions_dylibloader_wrapper_xlib)(XkbDescPtr, int, int); +extern int (*XkbChangeTypesOfKey_dylibloader_wrapper_xlib)(XkbDescPtr, int, int, unsigned int, int *, XkbMapChangesPtr); +extern int (*XkbChangeKeycodeRange_dylibloader_wrapper_xlib)(XkbDescPtr, int, int, XkbChangesPtr); +extern XkbComponentListPtr (*XkbListComponents_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbComponentNamesPtr, int *); +extern void (*XkbFreeComponentList_dylibloader_wrapper_xlib)(XkbComponentListPtr); +extern XkbDescPtr (*XkbGetKeyboard_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int); +extern XkbDescPtr (*XkbGetKeyboardByName_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbComponentNamesPtr, unsigned int, unsigned int, int); +extern int (*XkbKeyTypesForCoreSymbols_dylibloader_wrapper_xlib)(XkbDescPtr, int, KeySym *, unsigned int, int *, KeySym *); +extern int (*XkbApplyCompatMapToKey_dylibloader_wrapper_xlib)(XkbDescPtr, KeyCode, XkbChangesPtr); +extern int (*XkbUpdateMapFromCore_dylibloader_wrapper_xlib)(XkbDescPtr, KeyCode, int, int, KeySym *, XkbChangesPtr); +extern XkbDeviceLedInfoPtr (*XkbAddDeviceLedInfo_dylibloader_wrapper_xlib)(XkbDeviceInfoPtr, unsigned int, unsigned int); +extern int (*XkbResizeDeviceButtonActions_dylibloader_wrapper_xlib)(XkbDeviceInfoPtr, unsigned int); +extern XkbDeviceInfoPtr (*XkbAllocDeviceInfo_dylibloader_wrapper_xlib)(unsigned int, unsigned int, unsigned int); +extern void (*XkbFreeDeviceInfo_dylibloader_wrapper_xlib)(XkbDeviceInfoPtr, unsigned int, int); +extern void (*XkbNoteDeviceChanges_dylibloader_wrapper_xlib)(XkbDeviceChangesPtr, XkbExtensionDeviceNotifyEvent *, unsigned int); +extern XkbDeviceInfoPtr (*XkbGetDeviceInfo_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, unsigned int, unsigned int); +extern int (*XkbGetDeviceInfoChanges_dylibloader_wrapper_xlib)(Display *, XkbDeviceInfoPtr, XkbDeviceChangesPtr); +extern int (*XkbGetDeviceButtonActions_dylibloader_wrapper_xlib)(Display *, XkbDeviceInfoPtr, int, unsigned int, unsigned int); +extern int (*XkbGetDeviceLedInfo_dylibloader_wrapper_xlib)(Display *, XkbDeviceInfoPtr, unsigned int, unsigned int, unsigned int); +extern int (*XkbSetDeviceInfo_dylibloader_wrapper_xlib)(Display *, unsigned int, XkbDeviceInfoPtr); +extern int (*XkbChangeDeviceInfo_dylibloader_wrapper_xlib)(Display *, XkbDeviceInfoPtr, XkbDeviceChangesPtr); +extern int (*XkbSetDeviceLedInfo_dylibloader_wrapper_xlib)(Display *, XkbDeviceInfoPtr, unsigned int, unsigned int, unsigned int); +extern int (*XkbSetDeviceButtonActions_dylibloader_wrapper_xlib)(Display *, XkbDeviceInfoPtr, unsigned int, unsigned int); +extern char (*XkbToControl_dylibloader_wrapper_xlib)(char); +extern int (*XkbSetDebuggingFlags_dylibloader_wrapper_xlib)(Display *, unsigned int, unsigned int, char *, unsigned int, unsigned int, unsigned int *, unsigned int *); +extern int (*XkbApplyVirtualModChanges_dylibloader_wrapper_xlib)(XkbDescPtr, unsigned int, XkbChangesPtr); +extern int (*XkbUpdateActionVirtualMods_dylibloader_wrapper_xlib)(XkbDescPtr, XkbAction *, unsigned int); +extern void (*XkbUpdateKeyTypeVirtualMods_dylibloader_wrapper_xlib)(XkbDescPtr, XkbKeyTypePtr, unsigned int, XkbChangesPtr); int initialize_xlib(int verbose); #ifdef __cplusplus } diff --git a/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c index 05f98d2506..bc9de62caa 100644 --- a/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c +++ b/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c @@ -1,12 +1,8 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by generate-wrapper.py 0.3 on 2023-01-23 15:13:54 -// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h" --soname libXrandr.so.2 --init-name xrandr --output-header ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c +// generated by generate-wrapper.py 0.6 on 2024-11-09 02:52:37 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h --sys-include thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h --soname libXrandr.so.2 --init-name xrandr --output-header ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c --ignore-other // -// NOTE: Generated from Xrandr 1.5.2. -// This has been handpatched to workaround some issues with the generator that -// will be eventually fixed. In this case, non-existent symbols inherited from -// libX11 and libXrender, but absent in libXrandr.so.2, were removed. #include <stdint.h> #define XRRQueryExtension XRRQueryExtension_dylibloader_orig_xrandr @@ -152,76 +148,76 @@ #undef XRRFreeMonitors #include <dlfcn.h> #include <stdio.h> -int (*XRRQueryExtension_dylibloader_wrapper_xrandr)( Display*, int*, int*); -int (*XRRQueryVersion_dylibloader_wrapper_xrandr)( Display*, int*, int*); -XRRScreenConfiguration* (*XRRGetScreenInfo_dylibloader_wrapper_xrandr)( Display*, Window); -void (*XRRFreeScreenConfigInfo_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*); -int (*XRRSetScreenConfig_dylibloader_wrapper_xrandr)( Display*, XRRScreenConfiguration*, Drawable, int, Rotation, Time); -int (*XRRSetScreenConfigAndRate_dylibloader_wrapper_xrandr)( Display*, XRRScreenConfiguration*, Drawable, int, Rotation, short, Time); -Rotation (*XRRConfigRotations_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, Rotation*); -Time (*XRRConfigTimes_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, Time*); -XRRScreenSize* (*XRRConfigSizes_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, int*); -short* (*XRRConfigRates_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, int, int*); -SizeID (*XRRConfigCurrentConfiguration_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, Rotation*); -short (*XRRConfigCurrentRate_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*); -int (*XRRRootToScreen_dylibloader_wrapper_xrandr)( Display*, Window); -void (*XRRSelectInput_dylibloader_wrapper_xrandr)( Display*, Window, int); -Rotation (*XRRRotations_dylibloader_wrapper_xrandr)( Display*, int, Rotation*); -XRRScreenSize* (*XRRSizes_dylibloader_wrapper_xrandr)( Display*, int, int*); -short* (*XRRRates_dylibloader_wrapper_xrandr)( Display*, int, int, int*); -Time (*XRRTimes_dylibloader_wrapper_xrandr)( Display*, int, Time*); -int (*XRRGetScreenSizeRange_dylibloader_wrapper_xrandr)( Display*, Window, int*, int*, int*, int*); -void (*XRRSetScreenSize_dylibloader_wrapper_xrandr)( Display*, Window, int, int, int, int); -XRRScreenResources* (*XRRGetScreenResources_dylibloader_wrapper_xrandr)( Display*, Window); -void (*XRRFreeScreenResources_dylibloader_wrapper_xrandr)( XRRScreenResources*); -XRROutputInfo* (*XRRGetOutputInfo_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RROutput); -void (*XRRFreeOutputInfo_dylibloader_wrapper_xrandr)( XRROutputInfo*); -Atom* (*XRRListOutputProperties_dylibloader_wrapper_xrandr)( Display*, RROutput, int*); -XRRPropertyInfo* (*XRRQueryOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom); -void (*XRRConfigureOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom, int, int, int, long*); -void (*XRRChangeOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom, Atom, int, int,const unsigned char*, int); -void (*XRRDeleteOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom); -int (*XRRGetOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom, long, long, int, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); -XRRModeInfo* (*XRRAllocModeInfo_dylibloader_wrapper_xrandr)(const char*, int); -RRMode (*XRRCreateMode_dylibloader_wrapper_xrandr)( Display*, Window, XRRModeInfo*); -void (*XRRDestroyMode_dylibloader_wrapper_xrandr)( Display*, RRMode); -void (*XRRAddOutputMode_dylibloader_wrapper_xrandr)( Display*, RROutput, RRMode); -void (*XRRDeleteOutputMode_dylibloader_wrapper_xrandr)( Display*, RROutput, RRMode); -void (*XRRFreeModeInfo_dylibloader_wrapper_xrandr)( XRRModeInfo*); -XRRCrtcInfo* (*XRRGetCrtcInfo_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc); -void (*XRRFreeCrtcInfo_dylibloader_wrapper_xrandr)( XRRCrtcInfo*); -int (*XRRSetCrtcConfig_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc, Time, int, int, RRMode, Rotation, RROutput*, int); -int (*XRRGetCrtcGammaSize_dylibloader_wrapper_xrandr)( Display*, RRCrtc); -XRRCrtcGamma* (*XRRGetCrtcGamma_dylibloader_wrapper_xrandr)( Display*, RRCrtc); -XRRCrtcGamma* (*XRRAllocGamma_dylibloader_wrapper_xrandr)( int); -void (*XRRSetCrtcGamma_dylibloader_wrapper_xrandr)( Display*, RRCrtc, XRRCrtcGamma*); -void (*XRRFreeGamma_dylibloader_wrapper_xrandr)( XRRCrtcGamma*); -XRRScreenResources* (*XRRGetScreenResourcesCurrent_dylibloader_wrapper_xrandr)( Display*, Window); -void (*XRRSetCrtcTransform_dylibloader_wrapper_xrandr)( Display*, RRCrtc, XTransform*,const char*, XFixed*, int); -int (*XRRGetCrtcTransform_dylibloader_wrapper_xrandr)( Display*, RRCrtc, XRRCrtcTransformAttributes**); -int (*XRRUpdateConfiguration_dylibloader_wrapper_xrandr)( XEvent*); -XRRPanning* (*XRRGetPanning_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc); -void (*XRRFreePanning_dylibloader_wrapper_xrandr)( XRRPanning*); -int (*XRRSetPanning_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc, XRRPanning*); -void (*XRRSetOutputPrimary_dylibloader_wrapper_xrandr)( Display*, Window, RROutput); -RROutput (*XRRGetOutputPrimary_dylibloader_wrapper_xrandr)( Display*, Window); -XRRProviderResources* (*XRRGetProviderResources_dylibloader_wrapper_xrandr)( Display*, Window); -void (*XRRFreeProviderResources_dylibloader_wrapper_xrandr)( XRRProviderResources*); -XRRProviderInfo* (*XRRGetProviderInfo_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRProvider); -void (*XRRFreeProviderInfo_dylibloader_wrapper_xrandr)( XRRProviderInfo*); -int (*XRRSetProviderOutputSource_dylibloader_wrapper_xrandr)( Display*, XID, XID); -int (*XRRSetProviderOffloadSink_dylibloader_wrapper_xrandr)( Display*, XID, XID); -Atom* (*XRRListProviderProperties_dylibloader_wrapper_xrandr)( Display*, RRProvider, int*); -XRRPropertyInfo* (*XRRQueryProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom); -void (*XRRConfigureProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom, int, int, int, long*); -void (*XRRChangeProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom, Atom, int, int,const unsigned char*, int); -void (*XRRDeleteProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom); -int (*XRRGetProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom, long, long, int, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); -XRRMonitorInfo* (*XRRAllocateMonitor_dylibloader_wrapper_xrandr)( Display*, int); -XRRMonitorInfo* (*XRRGetMonitors_dylibloader_wrapper_xrandr)( Display*, Window, int, int*); -void (*XRRSetMonitor_dylibloader_wrapper_xrandr)( Display*, Window, XRRMonitorInfo*); -void (*XRRDeleteMonitor_dylibloader_wrapper_xrandr)( Display*, Window, Atom); -void (*XRRFreeMonitors_dylibloader_wrapper_xrandr)( XRRMonitorInfo*); +int (*XRRQueryExtension_dylibloader_wrapper_xrandr)(Display *, int *, int *); +int (*XRRQueryVersion_dylibloader_wrapper_xrandr)(Display *, int *, int *); +XRRScreenConfiguration *(*XRRGetScreenInfo_dylibloader_wrapper_xrandr)(Display *, Window); +void (*XRRFreeScreenConfigInfo_dylibloader_wrapper_xrandr)(XRRScreenConfiguration *); +int (*XRRSetScreenConfig_dylibloader_wrapper_xrandr)(Display *, XRRScreenConfiguration *, Drawable, int, Rotation, Time); +int (*XRRSetScreenConfigAndRate_dylibloader_wrapper_xrandr)(Display *, XRRScreenConfiguration *, Drawable, int, Rotation, short, Time); +Rotation (*XRRConfigRotations_dylibloader_wrapper_xrandr)(XRRScreenConfiguration *, Rotation *); +Time (*XRRConfigTimes_dylibloader_wrapper_xrandr)(XRRScreenConfiguration *, Time *); +XRRScreenSize *(*XRRConfigSizes_dylibloader_wrapper_xrandr)(XRRScreenConfiguration *, int *); +short *(*XRRConfigRates_dylibloader_wrapper_xrandr)(XRRScreenConfiguration *, int, int *); +SizeID (*XRRConfigCurrentConfiguration_dylibloader_wrapper_xrandr)(XRRScreenConfiguration *, Rotation *); +short (*XRRConfigCurrentRate_dylibloader_wrapper_xrandr)(XRRScreenConfiguration *); +int (*XRRRootToScreen_dylibloader_wrapper_xrandr)(Display *, Window); +void (*XRRSelectInput_dylibloader_wrapper_xrandr)(Display *, Window, int); +Rotation (*XRRRotations_dylibloader_wrapper_xrandr)(Display *, int, Rotation *); +XRRScreenSize *(*XRRSizes_dylibloader_wrapper_xrandr)(Display *, int, int *); +short *(*XRRRates_dylibloader_wrapper_xrandr)(Display *, int, int, int *); +Time (*XRRTimes_dylibloader_wrapper_xrandr)(Display *, int, Time *); +int (*XRRGetScreenSizeRange_dylibloader_wrapper_xrandr)(Display *, Window, int *, int *, int *, int *); +void (*XRRSetScreenSize_dylibloader_wrapper_xrandr)(Display *, Window, int, int, int, int); +XRRScreenResources *(*XRRGetScreenResources_dylibloader_wrapper_xrandr)(Display *, Window); +void (*XRRFreeScreenResources_dylibloader_wrapper_xrandr)(XRRScreenResources *); +XRROutputInfo *(*XRRGetOutputInfo_dylibloader_wrapper_xrandr)(Display *, XRRScreenResources *, RROutput); +void (*XRRFreeOutputInfo_dylibloader_wrapper_xrandr)(XRROutputInfo *); +Atom *(*XRRListOutputProperties_dylibloader_wrapper_xrandr)(Display *, RROutput, int *); +XRRPropertyInfo *(*XRRQueryOutputProperty_dylibloader_wrapper_xrandr)(Display *, RROutput, Atom); +void (*XRRConfigureOutputProperty_dylibloader_wrapper_xrandr)(Display *, RROutput, Atom, int, int, int, long *); +void (*XRRChangeOutputProperty_dylibloader_wrapper_xrandr)(Display *, RROutput, Atom, Atom, int, int, const unsigned char *, int); +void (*XRRDeleteOutputProperty_dylibloader_wrapper_xrandr)(Display *, RROutput, Atom); +int (*XRRGetOutputProperty_dylibloader_wrapper_xrandr)(Display *, RROutput, Atom, long, long, int, int, Atom, Atom *, int *, unsigned long *, unsigned long *, unsigned char **); +XRRModeInfo *(*XRRAllocModeInfo_dylibloader_wrapper_xrandr)(const char *, int); +RRMode (*XRRCreateMode_dylibloader_wrapper_xrandr)(Display *, Window, XRRModeInfo *); +void (*XRRDestroyMode_dylibloader_wrapper_xrandr)(Display *, RRMode); +void (*XRRAddOutputMode_dylibloader_wrapper_xrandr)(Display *, RROutput, RRMode); +void (*XRRDeleteOutputMode_dylibloader_wrapper_xrandr)(Display *, RROutput, RRMode); +void (*XRRFreeModeInfo_dylibloader_wrapper_xrandr)(XRRModeInfo *); +XRRCrtcInfo *(*XRRGetCrtcInfo_dylibloader_wrapper_xrandr)(Display *, XRRScreenResources *, RRCrtc); +void (*XRRFreeCrtcInfo_dylibloader_wrapper_xrandr)(XRRCrtcInfo *); +int (*XRRSetCrtcConfig_dylibloader_wrapper_xrandr)(Display *, XRRScreenResources *, RRCrtc, Time, int, int, RRMode, Rotation, RROutput *, int); +int (*XRRGetCrtcGammaSize_dylibloader_wrapper_xrandr)(Display *, RRCrtc); +XRRCrtcGamma *(*XRRGetCrtcGamma_dylibloader_wrapper_xrandr)(Display *, RRCrtc); +XRRCrtcGamma *(*XRRAllocGamma_dylibloader_wrapper_xrandr)(int); +void (*XRRSetCrtcGamma_dylibloader_wrapper_xrandr)(Display *, RRCrtc, XRRCrtcGamma *); +void (*XRRFreeGamma_dylibloader_wrapper_xrandr)(XRRCrtcGamma *); +XRRScreenResources *(*XRRGetScreenResourcesCurrent_dylibloader_wrapper_xrandr)(Display *, Window); +void (*XRRSetCrtcTransform_dylibloader_wrapper_xrandr)(Display *, RRCrtc, XTransform *, const char *, XFixed *, int); +int (*XRRGetCrtcTransform_dylibloader_wrapper_xrandr)(Display *, RRCrtc, XRRCrtcTransformAttributes **); +int (*XRRUpdateConfiguration_dylibloader_wrapper_xrandr)(XEvent *); +XRRPanning *(*XRRGetPanning_dylibloader_wrapper_xrandr)(Display *, XRRScreenResources *, RRCrtc); +void (*XRRFreePanning_dylibloader_wrapper_xrandr)(XRRPanning *); +int (*XRRSetPanning_dylibloader_wrapper_xrandr)(Display *, XRRScreenResources *, RRCrtc, XRRPanning *); +void (*XRRSetOutputPrimary_dylibloader_wrapper_xrandr)(Display *, Window, RROutput); +RROutput (*XRRGetOutputPrimary_dylibloader_wrapper_xrandr)(Display *, Window); +XRRProviderResources *(*XRRGetProviderResources_dylibloader_wrapper_xrandr)(Display *, Window); +void (*XRRFreeProviderResources_dylibloader_wrapper_xrandr)(XRRProviderResources *); +XRRProviderInfo *(*XRRGetProviderInfo_dylibloader_wrapper_xrandr)(Display *, XRRScreenResources *, RRProvider); +void (*XRRFreeProviderInfo_dylibloader_wrapper_xrandr)(XRRProviderInfo *); +int (*XRRSetProviderOutputSource_dylibloader_wrapper_xrandr)(Display *, XID, XID); +int (*XRRSetProviderOffloadSink_dylibloader_wrapper_xrandr)(Display *, XID, XID); +Atom *(*XRRListProviderProperties_dylibloader_wrapper_xrandr)(Display *, RRProvider, int *); +XRRPropertyInfo *(*XRRQueryProviderProperty_dylibloader_wrapper_xrandr)(Display *, RRProvider, Atom); +void (*XRRConfigureProviderProperty_dylibloader_wrapper_xrandr)(Display *, RRProvider, Atom, int, int, int, long *); +void (*XRRChangeProviderProperty_dylibloader_wrapper_xrandr)(Display *, RRProvider, Atom, Atom, int, int, const unsigned char *, int); +void (*XRRDeleteProviderProperty_dylibloader_wrapper_xrandr)(Display *, RRProvider, Atom); +int (*XRRGetProviderProperty_dylibloader_wrapper_xrandr)(Display *, RRProvider, Atom, long, long, int, int, Atom, Atom *, int *, unsigned long *, unsigned long *, unsigned char **); +XRRMonitorInfo *(*XRRAllocateMonitor_dylibloader_wrapper_xrandr)(Display *, int); +XRRMonitorInfo *(*XRRGetMonitors_dylibloader_wrapper_xrandr)(Display *, Window, int, int *); +void (*XRRSetMonitor_dylibloader_wrapper_xrandr)(Display *, Window, XRRMonitorInfo *); +void (*XRRDeleteMonitor_dylibloader_wrapper_xrandr)(Display *, Window, Atom); +void (*XRRFreeMonitors_dylibloader_wrapper_xrandr)(XRRMonitorInfo *); int initialize_xrandr(int verbose) { void *handle; char *error; diff --git a/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h index db5d44203d..c055705f69 100644 --- a/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h +++ b/platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h @@ -2,13 +2,9 @@ #define DYLIBLOAD_WRAPPER_XRANDR // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by generate-wrapper.py 0.3 on 2023-01-23 15:13:54 -// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h" --soname libXrandr.so.2 --init-name xrandr --output-header ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c +// generated by generate-wrapper.py 0.6 on 2024-11-09 02:52:37 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h --sys-include thirdparty/linuxbsd_headers/X11/extensions/Xrandr.h --soname libXrandr.so.2 --init-name xrandr --output-header ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrandr-so_wrap.c --ignore-other // -// NOTE: Generated from Xrandr 1.5.2. -// This has been handpatched to workaround some issues with the generator that -// will be eventually fixed. In this case, non-existent symbols inherited from -// libX11 and libXrender, but absent in libXrandr.so.2, were removed. #include <stdint.h> #define XRRQueryExtension XRRQueryExtension_dylibloader_orig_xrandr @@ -225,76 +221,76 @@ extern "C" { #define XRRSetMonitor XRRSetMonitor_dylibloader_wrapper_xrandr #define XRRDeleteMonitor XRRDeleteMonitor_dylibloader_wrapper_xrandr #define XRRFreeMonitors XRRFreeMonitors_dylibloader_wrapper_xrandr -extern int (*XRRQueryExtension_dylibloader_wrapper_xrandr)( Display*, int*, int*); -extern int (*XRRQueryVersion_dylibloader_wrapper_xrandr)( Display*, int*, int*); -extern XRRScreenConfiguration* (*XRRGetScreenInfo_dylibloader_wrapper_xrandr)( Display*, Window); -extern void (*XRRFreeScreenConfigInfo_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*); -extern int (*XRRSetScreenConfig_dylibloader_wrapper_xrandr)( Display*, XRRScreenConfiguration*, Drawable, int, Rotation, Time); -extern int (*XRRSetScreenConfigAndRate_dylibloader_wrapper_xrandr)( Display*, XRRScreenConfiguration*, Drawable, int, Rotation, short, Time); -extern Rotation (*XRRConfigRotations_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, Rotation*); -extern Time (*XRRConfigTimes_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, Time*); -extern XRRScreenSize* (*XRRConfigSizes_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, int*); -extern short* (*XRRConfigRates_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, int, int*); -extern SizeID (*XRRConfigCurrentConfiguration_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*, Rotation*); -extern short (*XRRConfigCurrentRate_dylibloader_wrapper_xrandr)( XRRScreenConfiguration*); -extern int (*XRRRootToScreen_dylibloader_wrapper_xrandr)( Display*, Window); -extern void (*XRRSelectInput_dylibloader_wrapper_xrandr)( Display*, Window, int); -extern Rotation (*XRRRotations_dylibloader_wrapper_xrandr)( Display*, int, Rotation*); -extern XRRScreenSize* (*XRRSizes_dylibloader_wrapper_xrandr)( Display*, int, int*); -extern short* (*XRRRates_dylibloader_wrapper_xrandr)( Display*, int, int, int*); -extern Time (*XRRTimes_dylibloader_wrapper_xrandr)( Display*, int, Time*); -extern int (*XRRGetScreenSizeRange_dylibloader_wrapper_xrandr)( Display*, Window, int*, int*, int*, int*); -extern void (*XRRSetScreenSize_dylibloader_wrapper_xrandr)( Display*, Window, int, int, int, int); -extern XRRScreenResources* (*XRRGetScreenResources_dylibloader_wrapper_xrandr)( Display*, Window); -extern void (*XRRFreeScreenResources_dylibloader_wrapper_xrandr)( XRRScreenResources*); -extern XRROutputInfo* (*XRRGetOutputInfo_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RROutput); -extern void (*XRRFreeOutputInfo_dylibloader_wrapper_xrandr)( XRROutputInfo*); -extern Atom* (*XRRListOutputProperties_dylibloader_wrapper_xrandr)( Display*, RROutput, int*); -extern XRRPropertyInfo* (*XRRQueryOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom); -extern void (*XRRConfigureOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom, int, int, int, long*); -extern void (*XRRChangeOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom, Atom, int, int,const unsigned char*, int); -extern void (*XRRDeleteOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom); -extern int (*XRRGetOutputProperty_dylibloader_wrapper_xrandr)( Display*, RROutput, Atom, long, long, int, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); -extern XRRModeInfo* (*XRRAllocModeInfo_dylibloader_wrapper_xrandr)(const char*, int); -extern RRMode (*XRRCreateMode_dylibloader_wrapper_xrandr)( Display*, Window, XRRModeInfo*); -extern void (*XRRDestroyMode_dylibloader_wrapper_xrandr)( Display*, RRMode); -extern void (*XRRAddOutputMode_dylibloader_wrapper_xrandr)( Display*, RROutput, RRMode); -extern void (*XRRDeleteOutputMode_dylibloader_wrapper_xrandr)( Display*, RROutput, RRMode); -extern void (*XRRFreeModeInfo_dylibloader_wrapper_xrandr)( XRRModeInfo*); -extern XRRCrtcInfo* (*XRRGetCrtcInfo_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc); -extern void (*XRRFreeCrtcInfo_dylibloader_wrapper_xrandr)( XRRCrtcInfo*); -extern int (*XRRSetCrtcConfig_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc, Time, int, int, RRMode, Rotation, RROutput*, int); -extern int (*XRRGetCrtcGammaSize_dylibloader_wrapper_xrandr)( Display*, RRCrtc); -extern XRRCrtcGamma* (*XRRGetCrtcGamma_dylibloader_wrapper_xrandr)( Display*, RRCrtc); -extern XRRCrtcGamma* (*XRRAllocGamma_dylibloader_wrapper_xrandr)( int); -extern void (*XRRSetCrtcGamma_dylibloader_wrapper_xrandr)( Display*, RRCrtc, XRRCrtcGamma*); -extern void (*XRRFreeGamma_dylibloader_wrapper_xrandr)( XRRCrtcGamma*); -extern XRRScreenResources* (*XRRGetScreenResourcesCurrent_dylibloader_wrapper_xrandr)( Display*, Window); -extern void (*XRRSetCrtcTransform_dylibloader_wrapper_xrandr)( Display*, RRCrtc, XTransform*,const char*, XFixed*, int); -extern int (*XRRGetCrtcTransform_dylibloader_wrapper_xrandr)( Display*, RRCrtc, XRRCrtcTransformAttributes**); -extern int (*XRRUpdateConfiguration_dylibloader_wrapper_xrandr)( XEvent*); -extern XRRPanning* (*XRRGetPanning_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc); -extern void (*XRRFreePanning_dylibloader_wrapper_xrandr)( XRRPanning*); -extern int (*XRRSetPanning_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRCrtc, XRRPanning*); -extern void (*XRRSetOutputPrimary_dylibloader_wrapper_xrandr)( Display*, Window, RROutput); -extern RROutput (*XRRGetOutputPrimary_dylibloader_wrapper_xrandr)( Display*, Window); -extern XRRProviderResources* (*XRRGetProviderResources_dylibloader_wrapper_xrandr)( Display*, Window); -extern void (*XRRFreeProviderResources_dylibloader_wrapper_xrandr)( XRRProviderResources*); -extern XRRProviderInfo* (*XRRGetProviderInfo_dylibloader_wrapper_xrandr)( Display*, XRRScreenResources*, RRProvider); -extern void (*XRRFreeProviderInfo_dylibloader_wrapper_xrandr)( XRRProviderInfo*); -extern int (*XRRSetProviderOutputSource_dylibloader_wrapper_xrandr)( Display*, XID, XID); -extern int (*XRRSetProviderOffloadSink_dylibloader_wrapper_xrandr)( Display*, XID, XID); -extern Atom* (*XRRListProviderProperties_dylibloader_wrapper_xrandr)( Display*, RRProvider, int*); -extern XRRPropertyInfo* (*XRRQueryProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom); -extern void (*XRRConfigureProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom, int, int, int, long*); -extern void (*XRRChangeProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom, Atom, int, int,const unsigned char*, int); -extern void (*XRRDeleteProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom); -extern int (*XRRGetProviderProperty_dylibloader_wrapper_xrandr)( Display*, RRProvider, Atom, long, long, int, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**); -extern XRRMonitorInfo* (*XRRAllocateMonitor_dylibloader_wrapper_xrandr)( Display*, int); -extern XRRMonitorInfo* (*XRRGetMonitors_dylibloader_wrapper_xrandr)( Display*, Window, int, int*); -extern void (*XRRSetMonitor_dylibloader_wrapper_xrandr)( Display*, Window, XRRMonitorInfo*); -extern void (*XRRDeleteMonitor_dylibloader_wrapper_xrandr)( Display*, Window, Atom); -extern void (*XRRFreeMonitors_dylibloader_wrapper_xrandr)( XRRMonitorInfo*); +extern int (*XRRQueryExtension_dylibloader_wrapper_xrandr)(Display *, int *, int *); +extern int (*XRRQueryVersion_dylibloader_wrapper_xrandr)(Display *, int *, int *); +extern XRRScreenConfiguration *(*XRRGetScreenInfo_dylibloader_wrapper_xrandr)(Display *, Window); +extern void (*XRRFreeScreenConfigInfo_dylibloader_wrapper_xrandr)(XRRScreenConfiguration *); +extern int (*XRRSetScreenConfig_dylibloader_wrapper_xrandr)(Display *, XRRScreenConfiguration *, Drawable, int, Rotation, Time); +extern int (*XRRSetScreenConfigAndRate_dylibloader_wrapper_xrandr)(Display *, XRRScreenConfiguration *, Drawable, int, Rotation, short, Time); +extern Rotation (*XRRConfigRotations_dylibloader_wrapper_xrandr)(XRRScreenConfiguration *, Rotation *); +extern Time (*XRRConfigTimes_dylibloader_wrapper_xrandr)(XRRScreenConfiguration *, Time *); +extern XRRScreenSize *(*XRRConfigSizes_dylibloader_wrapper_xrandr)(XRRScreenConfiguration *, int *); +extern short *(*XRRConfigRates_dylibloader_wrapper_xrandr)(XRRScreenConfiguration *, int, int *); +extern SizeID (*XRRConfigCurrentConfiguration_dylibloader_wrapper_xrandr)(XRRScreenConfiguration *, Rotation *); +extern short (*XRRConfigCurrentRate_dylibloader_wrapper_xrandr)(XRRScreenConfiguration *); +extern int (*XRRRootToScreen_dylibloader_wrapper_xrandr)(Display *, Window); +extern void (*XRRSelectInput_dylibloader_wrapper_xrandr)(Display *, Window, int); +extern Rotation (*XRRRotations_dylibloader_wrapper_xrandr)(Display *, int, Rotation *); +extern XRRScreenSize *(*XRRSizes_dylibloader_wrapper_xrandr)(Display *, int, int *); +extern short *(*XRRRates_dylibloader_wrapper_xrandr)(Display *, int, int, int *); +extern Time (*XRRTimes_dylibloader_wrapper_xrandr)(Display *, int, Time *); +extern int (*XRRGetScreenSizeRange_dylibloader_wrapper_xrandr)(Display *, Window, int *, int *, int *, int *); +extern void (*XRRSetScreenSize_dylibloader_wrapper_xrandr)(Display *, Window, int, int, int, int); +extern XRRScreenResources *(*XRRGetScreenResources_dylibloader_wrapper_xrandr)(Display *, Window); +extern void (*XRRFreeScreenResources_dylibloader_wrapper_xrandr)(XRRScreenResources *); +extern XRROutputInfo *(*XRRGetOutputInfo_dylibloader_wrapper_xrandr)(Display *, XRRScreenResources *, RROutput); +extern void (*XRRFreeOutputInfo_dylibloader_wrapper_xrandr)(XRROutputInfo *); +extern Atom *(*XRRListOutputProperties_dylibloader_wrapper_xrandr)(Display *, RROutput, int *); +extern XRRPropertyInfo *(*XRRQueryOutputProperty_dylibloader_wrapper_xrandr)(Display *, RROutput, Atom); +extern void (*XRRConfigureOutputProperty_dylibloader_wrapper_xrandr)(Display *, RROutput, Atom, int, int, int, long *); +extern void (*XRRChangeOutputProperty_dylibloader_wrapper_xrandr)(Display *, RROutput, Atom, Atom, int, int, const unsigned char *, int); +extern void (*XRRDeleteOutputProperty_dylibloader_wrapper_xrandr)(Display *, RROutput, Atom); +extern int (*XRRGetOutputProperty_dylibloader_wrapper_xrandr)(Display *, RROutput, Atom, long, long, int, int, Atom, Atom *, int *, unsigned long *, unsigned long *, unsigned char **); +extern XRRModeInfo *(*XRRAllocModeInfo_dylibloader_wrapper_xrandr)(const char *, int); +extern RRMode (*XRRCreateMode_dylibloader_wrapper_xrandr)(Display *, Window, XRRModeInfo *); +extern void (*XRRDestroyMode_dylibloader_wrapper_xrandr)(Display *, RRMode); +extern void (*XRRAddOutputMode_dylibloader_wrapper_xrandr)(Display *, RROutput, RRMode); +extern void (*XRRDeleteOutputMode_dylibloader_wrapper_xrandr)(Display *, RROutput, RRMode); +extern void (*XRRFreeModeInfo_dylibloader_wrapper_xrandr)(XRRModeInfo *); +extern XRRCrtcInfo *(*XRRGetCrtcInfo_dylibloader_wrapper_xrandr)(Display *, XRRScreenResources *, RRCrtc); +extern void (*XRRFreeCrtcInfo_dylibloader_wrapper_xrandr)(XRRCrtcInfo *); +extern int (*XRRSetCrtcConfig_dylibloader_wrapper_xrandr)(Display *, XRRScreenResources *, RRCrtc, Time, int, int, RRMode, Rotation, RROutput *, int); +extern int (*XRRGetCrtcGammaSize_dylibloader_wrapper_xrandr)(Display *, RRCrtc); +extern XRRCrtcGamma *(*XRRGetCrtcGamma_dylibloader_wrapper_xrandr)(Display *, RRCrtc); +extern XRRCrtcGamma *(*XRRAllocGamma_dylibloader_wrapper_xrandr)(int); +extern void (*XRRSetCrtcGamma_dylibloader_wrapper_xrandr)(Display *, RRCrtc, XRRCrtcGamma *); +extern void (*XRRFreeGamma_dylibloader_wrapper_xrandr)(XRRCrtcGamma *); +extern XRRScreenResources *(*XRRGetScreenResourcesCurrent_dylibloader_wrapper_xrandr)(Display *, Window); +extern void (*XRRSetCrtcTransform_dylibloader_wrapper_xrandr)(Display *, RRCrtc, XTransform *, const char *, XFixed *, int); +extern int (*XRRGetCrtcTransform_dylibloader_wrapper_xrandr)(Display *, RRCrtc, XRRCrtcTransformAttributes **); +extern int (*XRRUpdateConfiguration_dylibloader_wrapper_xrandr)(XEvent *); +extern XRRPanning *(*XRRGetPanning_dylibloader_wrapper_xrandr)(Display *, XRRScreenResources *, RRCrtc); +extern void (*XRRFreePanning_dylibloader_wrapper_xrandr)(XRRPanning *); +extern int (*XRRSetPanning_dylibloader_wrapper_xrandr)(Display *, XRRScreenResources *, RRCrtc, XRRPanning *); +extern void (*XRRSetOutputPrimary_dylibloader_wrapper_xrandr)(Display *, Window, RROutput); +extern RROutput (*XRRGetOutputPrimary_dylibloader_wrapper_xrandr)(Display *, Window); +extern XRRProviderResources *(*XRRGetProviderResources_dylibloader_wrapper_xrandr)(Display *, Window); +extern void (*XRRFreeProviderResources_dylibloader_wrapper_xrandr)(XRRProviderResources *); +extern XRRProviderInfo *(*XRRGetProviderInfo_dylibloader_wrapper_xrandr)(Display *, XRRScreenResources *, RRProvider); +extern void (*XRRFreeProviderInfo_dylibloader_wrapper_xrandr)(XRRProviderInfo *); +extern int (*XRRSetProviderOutputSource_dylibloader_wrapper_xrandr)(Display *, XID, XID); +extern int (*XRRSetProviderOffloadSink_dylibloader_wrapper_xrandr)(Display *, XID, XID); +extern Atom *(*XRRListProviderProperties_dylibloader_wrapper_xrandr)(Display *, RRProvider, int *); +extern XRRPropertyInfo *(*XRRQueryProviderProperty_dylibloader_wrapper_xrandr)(Display *, RRProvider, Atom); +extern void (*XRRConfigureProviderProperty_dylibloader_wrapper_xrandr)(Display *, RRProvider, Atom, int, int, int, long *); +extern void (*XRRChangeProviderProperty_dylibloader_wrapper_xrandr)(Display *, RRProvider, Atom, Atom, int, int, const unsigned char *, int); +extern void (*XRRDeleteProviderProperty_dylibloader_wrapper_xrandr)(Display *, RRProvider, Atom); +extern int (*XRRGetProviderProperty_dylibloader_wrapper_xrandr)(Display *, RRProvider, Atom, long, long, int, int, Atom, Atom *, int *, unsigned long *, unsigned long *, unsigned char **); +extern XRRMonitorInfo *(*XRRAllocateMonitor_dylibloader_wrapper_xrandr)(Display *, int); +extern XRRMonitorInfo *(*XRRGetMonitors_dylibloader_wrapper_xrandr)(Display *, Window, int, int *); +extern void (*XRRSetMonitor_dylibloader_wrapper_xrandr)(Display *, Window, XRRMonitorInfo *); +extern void (*XRRDeleteMonitor_dylibloader_wrapper_xrandr)(Display *, Window, Atom); +extern void (*XRRFreeMonitors_dylibloader_wrapper_xrandr)(XRRMonitorInfo *); int initialize_xrandr(int verbose); #ifdef __cplusplus } diff --git a/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c b/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c index 7421f94601..e1cd987eca 100644 --- a/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c +++ b/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c @@ -1,12 +1,8 @@ // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by generate-wrapper.py 0.3 on 2023-01-23 15:14:14 -// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrender.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xrender.h" --soname libXrender.so.1 --init-name xrender --output-header ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c~ +// generated by generate-wrapper.py 0.6 on 2024-11-09 02:52:37 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrender.h --sys-include thirdparty/linuxbsd_headers/X11/extensions/Xrender.h --soname libXrender.so.1 --init-name xrender --output-header ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c --ignore-other // -// NOTE: Generated from Xrender 0.9.10. -// This has been handpatched to workaround some issues with the generator that -// will be eventually fixed. In this case, non-existent symbols inherited from -// libX11, but absent in libXrender.so.1, were removed. #include <stdint.h> #define XRenderQueryExtension XRenderQueryExtension_dylibloader_orig_xrender @@ -100,50 +96,50 @@ #undef XRenderCreateConicalGradient #include <dlfcn.h> #include <stdio.h> -int (*XRenderQueryExtension_dylibloader_wrapper_xrender)( Display*, int*, int*); -int (*XRenderQueryVersion_dylibloader_wrapper_xrender)( Display*, int*, int*); -int (*XRenderQueryFormats_dylibloader_wrapper_xrender)( Display*); -int (*XRenderQuerySubpixelOrder_dylibloader_wrapper_xrender)( Display*, int); -int (*XRenderSetSubpixelOrder_dylibloader_wrapper_xrender)( Display*, int, int); -XRenderPictFormat* (*XRenderFindVisualFormat_dylibloader_wrapper_xrender)( Display*,const Visual*); -XRenderPictFormat* (*XRenderFindFormat_dylibloader_wrapper_xrender)( Display*, unsigned long,const XRenderPictFormat*, int); -XRenderPictFormat* (*XRenderFindStandardFormat_dylibloader_wrapper_xrender)( Display*, int); -XIndexValue* (*XRenderQueryPictIndexValues_dylibloader_wrapper_xrender)( Display*,const XRenderPictFormat*, int*); -Picture (*XRenderCreatePicture_dylibloader_wrapper_xrender)( Display*, Drawable,const XRenderPictFormat*, unsigned long,const XRenderPictureAttributes*); -void (*XRenderChangePicture_dylibloader_wrapper_xrender)( Display*, Picture, unsigned long,const XRenderPictureAttributes*); -void (*XRenderSetPictureClipRectangles_dylibloader_wrapper_xrender)( Display*, Picture, int, int,const XRectangle*, int); -void (*XRenderSetPictureClipRegion_dylibloader_wrapper_xrender)( Display*, Picture, Region); -void (*XRenderSetPictureTransform_dylibloader_wrapper_xrender)( Display*, Picture, XTransform*); -void (*XRenderFreePicture_dylibloader_wrapper_xrender)( Display*, Picture); -void (*XRenderComposite_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture, Picture, int, int, int, int, int, int, unsigned int, unsigned int); -GlyphSet (*XRenderCreateGlyphSet_dylibloader_wrapper_xrender)( Display*,const XRenderPictFormat*); -GlyphSet (*XRenderReferenceGlyphSet_dylibloader_wrapper_xrender)( Display*, GlyphSet); -void (*XRenderFreeGlyphSet_dylibloader_wrapper_xrender)( Display*, GlyphSet); -void (*XRenderAddGlyphs_dylibloader_wrapper_xrender)( Display*, GlyphSet,const Glyph*,const XGlyphInfo*, int,const char*, int); -void (*XRenderFreeGlyphs_dylibloader_wrapper_xrender)( Display*, GlyphSet,const Glyph*, int); -void (*XRenderCompositeString8_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, GlyphSet, int, int, int, int,const char*, int); -void (*XRenderCompositeString16_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, GlyphSet, int, int, int, int,const unsigned short*, int); -void (*XRenderCompositeString32_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, GlyphSet, int, int, int, int,const unsigned int*, int); -void (*XRenderCompositeText8_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XGlyphElt8*, int); -void (*XRenderCompositeText16_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XGlyphElt16*, int); -void (*XRenderCompositeText32_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XGlyphElt32*, int); -void (*XRenderFillRectangle_dylibloader_wrapper_xrender)( Display*, int, Picture,const XRenderColor*, int, int, unsigned int, unsigned int); -void (*XRenderFillRectangles_dylibloader_wrapper_xrender)( Display*, int, Picture,const XRenderColor*,const XRectangle*, int); -void (*XRenderCompositeTrapezoids_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XTrapezoid*, int); -void (*XRenderCompositeTriangles_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XTriangle*, int); -void (*XRenderCompositeTriStrip_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XPointFixed*, int); -void (*XRenderCompositeTriFan_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XPointFixed*, int); -void (*XRenderCompositeDoublePoly_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XPointDouble*, int, int); -int (*XRenderParseColor_dylibloader_wrapper_xrender)( Display*, char*, XRenderColor*); -Cursor (*XRenderCreateCursor_dylibloader_wrapper_xrender)( Display*, Picture, unsigned int, unsigned int); -XFilters* (*XRenderQueryFilters_dylibloader_wrapper_xrender)( Display*, Drawable); -void (*XRenderSetPictureFilter_dylibloader_wrapper_xrender)( Display*, Picture,const char*, XFixed*, int); -Cursor (*XRenderCreateAnimCursor_dylibloader_wrapper_xrender)( Display*, int, XAnimCursor*); -void (*XRenderAddTraps_dylibloader_wrapper_xrender)( Display*, Picture, int, int,const XTrap*, int); -Picture (*XRenderCreateSolidFill_dylibloader_wrapper_xrender)( Display*,const XRenderColor*); -Picture (*XRenderCreateLinearGradient_dylibloader_wrapper_xrender)( Display*,const XLinearGradient*,const XFixed*,const XRenderColor*, int); -Picture (*XRenderCreateRadialGradient_dylibloader_wrapper_xrender)( Display*,const XRadialGradient*,const XFixed*,const XRenderColor*, int); -Picture (*XRenderCreateConicalGradient_dylibloader_wrapper_xrender)( Display*,const XConicalGradient*,const XFixed*,const XRenderColor*, int); +int (*XRenderQueryExtension_dylibloader_wrapper_xrender)(Display *, int *, int *); +int (*XRenderQueryVersion_dylibloader_wrapper_xrender)(Display *, int *, int *); +int (*XRenderQueryFormats_dylibloader_wrapper_xrender)(Display *); +int (*XRenderQuerySubpixelOrder_dylibloader_wrapper_xrender)(Display *, int); +int (*XRenderSetSubpixelOrder_dylibloader_wrapper_xrender)(Display *, int, int); +XRenderPictFormat *(*XRenderFindVisualFormat_dylibloader_wrapper_xrender)(Display *, const Visual *); +XRenderPictFormat *(*XRenderFindFormat_dylibloader_wrapper_xrender)(Display *, unsigned long, const XRenderPictFormat *, int); +XRenderPictFormat *(*XRenderFindStandardFormat_dylibloader_wrapper_xrender)(Display *, int); +XIndexValue *(*XRenderQueryPictIndexValues_dylibloader_wrapper_xrender)(Display *, const XRenderPictFormat *, int *); +Picture (*XRenderCreatePicture_dylibloader_wrapper_xrender)(Display *, Drawable, const XRenderPictFormat *, unsigned long, const XRenderPictureAttributes *); +void (*XRenderChangePicture_dylibloader_wrapper_xrender)(Display *, Picture, unsigned long, const XRenderPictureAttributes *); +void (*XRenderSetPictureClipRectangles_dylibloader_wrapper_xrender)(Display *, Picture, int, int, const XRectangle *, int); +void (*XRenderSetPictureClipRegion_dylibloader_wrapper_xrender)(Display *, Picture, Region); +void (*XRenderSetPictureTransform_dylibloader_wrapper_xrender)(Display *, Picture, XTransform *); +void (*XRenderFreePicture_dylibloader_wrapper_xrender)(Display *, Picture); +void (*XRenderComposite_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, Picture, int, int, int, int, int, int, unsigned int, unsigned int); +GlyphSet (*XRenderCreateGlyphSet_dylibloader_wrapper_xrender)(Display *, const XRenderPictFormat *); +GlyphSet (*XRenderReferenceGlyphSet_dylibloader_wrapper_xrender)(Display *, GlyphSet); +void (*XRenderFreeGlyphSet_dylibloader_wrapper_xrender)(Display *, GlyphSet); +void (*XRenderAddGlyphs_dylibloader_wrapper_xrender)(Display *, GlyphSet, const Glyph *, const XGlyphInfo *, int, const char *, int); +void (*XRenderFreeGlyphs_dylibloader_wrapper_xrender)(Display *, GlyphSet, const Glyph *, int); +void (*XRenderCompositeString8_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, GlyphSet, int, int, int, int, const char *, int); +void (*XRenderCompositeString16_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, GlyphSet, int, int, int, int, const unsigned short *, int); +void (*XRenderCompositeString32_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, GlyphSet, int, int, int, int, const unsigned int *, int); +void (*XRenderCompositeText8_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, int, int, const XGlyphElt8 *, int); +void (*XRenderCompositeText16_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, int, int, const XGlyphElt16 *, int); +void (*XRenderCompositeText32_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, int, int, const XGlyphElt32 *, int); +void (*XRenderFillRectangle_dylibloader_wrapper_xrender)(Display *, int, Picture, const XRenderColor *, int, int, unsigned int, unsigned int); +void (*XRenderFillRectangles_dylibloader_wrapper_xrender)(Display *, int, Picture, const XRenderColor *, const XRectangle *, int); +void (*XRenderCompositeTrapezoids_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, const XTrapezoid *, int); +void (*XRenderCompositeTriangles_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, const XTriangle *, int); +void (*XRenderCompositeTriStrip_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, const XPointFixed *, int); +void (*XRenderCompositeTriFan_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, const XPointFixed *, int); +void (*XRenderCompositeDoublePoly_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, int, int, const XPointDouble *, int, int); +int (*XRenderParseColor_dylibloader_wrapper_xrender)(Display *, char *, XRenderColor *); +Cursor (*XRenderCreateCursor_dylibloader_wrapper_xrender)(Display *, Picture, unsigned int, unsigned int); +XFilters *(*XRenderQueryFilters_dylibloader_wrapper_xrender)(Display *, Drawable); +void (*XRenderSetPictureFilter_dylibloader_wrapper_xrender)(Display *, Picture, const char *, XFixed *, int); +Cursor (*XRenderCreateAnimCursor_dylibloader_wrapper_xrender)(Display *, int, XAnimCursor *); +void (*XRenderAddTraps_dylibloader_wrapper_xrender)(Display *, Picture, int, int, const XTrap *, int); +Picture (*XRenderCreateSolidFill_dylibloader_wrapper_xrender)(Display *, const XRenderColor *); +Picture (*XRenderCreateLinearGradient_dylibloader_wrapper_xrender)(Display *, const XLinearGradient *, const XFixed *, const XRenderColor *, int); +Picture (*XRenderCreateRadialGradient_dylibloader_wrapper_xrender)(Display *, const XRadialGradient *, const XFixed *, const XRenderColor *, int); +Picture (*XRenderCreateConicalGradient_dylibloader_wrapper_xrender)(Display *, const XConicalGradient *, const XFixed *, const XRenderColor *, int); int initialize_xrender(int verbose) { void *handle; char *error; diff --git a/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h b/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h index 5d3f695959..3d0e8901ea 100644 --- a/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h +++ b/platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h @@ -2,13 +2,9 @@ #define DYLIBLOAD_WRAPPER_XRENDER // This file is generated. Do not edit! // see https://github.com/hpvb/dynload-wrapper for details -// generated by generate-wrapper.py 0.3 on 2023-01-23 15:14:14 -// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrender.h --sys-include "thirdparty/linuxbsd_headers/X11/extensions/Xrender.h" --soname libXrender.so.1 --init-name xrender --output-header ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c~ +// generated by generate-wrapper.py 0.6 on 2024-11-09 02:52:37 +// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/X11/extensions/Xrender.h --sys-include thirdparty/linuxbsd_headers/X11/extensions/Xrender.h --soname libXrender.so.1 --init-name xrender --output-header ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.h --output-implementation ./platform/linuxbsd/x11/dynwrappers/xrender-so_wrap.c --ignore-other // -// NOTE: Generated from Xrender 0.9.10. -// This has been handpatched to workaround some issues with the generator that -// will be eventually fixed. In this case, non-existent symbols inherited from -// libX11, but absent in libXrender.so.1, were removed. #include <stdint.h> #define XRenderQueryExtension XRenderQueryExtension_dylibloader_orig_xrender @@ -147,50 +143,50 @@ extern "C" { #define XRenderCreateLinearGradient XRenderCreateLinearGradient_dylibloader_wrapper_xrender #define XRenderCreateRadialGradient XRenderCreateRadialGradient_dylibloader_wrapper_xrender #define XRenderCreateConicalGradient XRenderCreateConicalGradient_dylibloader_wrapper_xrender -extern int (*XRenderQueryExtension_dylibloader_wrapper_xrender)( Display*, int*, int*); -extern int (*XRenderQueryVersion_dylibloader_wrapper_xrender)( Display*, int*, int*); -extern int (*XRenderQueryFormats_dylibloader_wrapper_xrender)( Display*); -extern int (*XRenderQuerySubpixelOrder_dylibloader_wrapper_xrender)( Display*, int); -extern int (*XRenderSetSubpixelOrder_dylibloader_wrapper_xrender)( Display*, int, int); -extern XRenderPictFormat* (*XRenderFindVisualFormat_dylibloader_wrapper_xrender)( Display*,const Visual*); -extern XRenderPictFormat* (*XRenderFindFormat_dylibloader_wrapper_xrender)( Display*, unsigned long,const XRenderPictFormat*, int); -extern XRenderPictFormat* (*XRenderFindStandardFormat_dylibloader_wrapper_xrender)( Display*, int); -extern XIndexValue* (*XRenderQueryPictIndexValues_dylibloader_wrapper_xrender)( Display*,const XRenderPictFormat*, int*); -extern Picture (*XRenderCreatePicture_dylibloader_wrapper_xrender)( Display*, Drawable,const XRenderPictFormat*, unsigned long,const XRenderPictureAttributes*); -extern void (*XRenderChangePicture_dylibloader_wrapper_xrender)( Display*, Picture, unsigned long,const XRenderPictureAttributes*); -extern void (*XRenderSetPictureClipRectangles_dylibloader_wrapper_xrender)( Display*, Picture, int, int,const XRectangle*, int); -extern void (*XRenderSetPictureClipRegion_dylibloader_wrapper_xrender)( Display*, Picture, Region); -extern void (*XRenderSetPictureTransform_dylibloader_wrapper_xrender)( Display*, Picture, XTransform*); -extern void (*XRenderFreePicture_dylibloader_wrapper_xrender)( Display*, Picture); -extern void (*XRenderComposite_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture, Picture, int, int, int, int, int, int, unsigned int, unsigned int); -extern GlyphSet (*XRenderCreateGlyphSet_dylibloader_wrapper_xrender)( Display*,const XRenderPictFormat*); -extern GlyphSet (*XRenderReferenceGlyphSet_dylibloader_wrapper_xrender)( Display*, GlyphSet); -extern void (*XRenderFreeGlyphSet_dylibloader_wrapper_xrender)( Display*, GlyphSet); -extern void (*XRenderAddGlyphs_dylibloader_wrapper_xrender)( Display*, GlyphSet,const Glyph*,const XGlyphInfo*, int,const char*, int); -extern void (*XRenderFreeGlyphs_dylibloader_wrapper_xrender)( Display*, GlyphSet,const Glyph*, int); -extern void (*XRenderCompositeString8_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, GlyphSet, int, int, int, int,const char*, int); -extern void (*XRenderCompositeString16_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, GlyphSet, int, int, int, int,const unsigned short*, int); -extern void (*XRenderCompositeString32_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, GlyphSet, int, int, int, int,const unsigned int*, int); -extern void (*XRenderCompositeText8_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XGlyphElt8*, int); -extern void (*XRenderCompositeText16_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XGlyphElt16*, int); -extern void (*XRenderCompositeText32_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XGlyphElt32*, int); -extern void (*XRenderFillRectangle_dylibloader_wrapper_xrender)( Display*, int, Picture,const XRenderColor*, int, int, unsigned int, unsigned int); -extern void (*XRenderFillRectangles_dylibloader_wrapper_xrender)( Display*, int, Picture,const XRenderColor*,const XRectangle*, int); -extern void (*XRenderCompositeTrapezoids_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XTrapezoid*, int); -extern void (*XRenderCompositeTriangles_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XTriangle*, int); -extern void (*XRenderCompositeTriStrip_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XPointFixed*, int); -extern void (*XRenderCompositeTriFan_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int,const XPointFixed*, int); -extern void (*XRenderCompositeDoublePoly_dylibloader_wrapper_xrender)( Display*, int, Picture, Picture,const XRenderPictFormat*, int, int, int, int,const XPointDouble*, int, int); -extern int (*XRenderParseColor_dylibloader_wrapper_xrender)( Display*, char*, XRenderColor*); -extern Cursor (*XRenderCreateCursor_dylibloader_wrapper_xrender)( Display*, Picture, unsigned int, unsigned int); -extern XFilters* (*XRenderQueryFilters_dylibloader_wrapper_xrender)( Display*, Drawable); -extern void (*XRenderSetPictureFilter_dylibloader_wrapper_xrender)( Display*, Picture,const char*, XFixed*, int); -extern Cursor (*XRenderCreateAnimCursor_dylibloader_wrapper_xrender)( Display*, int, XAnimCursor*); -extern void (*XRenderAddTraps_dylibloader_wrapper_xrender)( Display*, Picture, int, int,const XTrap*, int); -extern Picture (*XRenderCreateSolidFill_dylibloader_wrapper_xrender)( Display*,const XRenderColor*); -extern Picture (*XRenderCreateLinearGradient_dylibloader_wrapper_xrender)( Display*,const XLinearGradient*,const XFixed*,const XRenderColor*, int); -extern Picture (*XRenderCreateRadialGradient_dylibloader_wrapper_xrender)( Display*,const XRadialGradient*,const XFixed*,const XRenderColor*, int); -extern Picture (*XRenderCreateConicalGradient_dylibloader_wrapper_xrender)( Display*,const XConicalGradient*,const XFixed*,const XRenderColor*, int); +extern int (*XRenderQueryExtension_dylibloader_wrapper_xrender)(Display *, int *, int *); +extern int (*XRenderQueryVersion_dylibloader_wrapper_xrender)(Display *, int *, int *); +extern int (*XRenderQueryFormats_dylibloader_wrapper_xrender)(Display *); +extern int (*XRenderQuerySubpixelOrder_dylibloader_wrapper_xrender)(Display *, int); +extern int (*XRenderSetSubpixelOrder_dylibloader_wrapper_xrender)(Display *, int, int); +extern XRenderPictFormat *(*XRenderFindVisualFormat_dylibloader_wrapper_xrender)(Display *, const Visual *); +extern XRenderPictFormat *(*XRenderFindFormat_dylibloader_wrapper_xrender)(Display *, unsigned long, const XRenderPictFormat *, int); +extern XRenderPictFormat *(*XRenderFindStandardFormat_dylibloader_wrapper_xrender)(Display *, int); +extern XIndexValue *(*XRenderQueryPictIndexValues_dylibloader_wrapper_xrender)(Display *, const XRenderPictFormat *, int *); +extern Picture (*XRenderCreatePicture_dylibloader_wrapper_xrender)(Display *, Drawable, const XRenderPictFormat *, unsigned long, const XRenderPictureAttributes *); +extern void (*XRenderChangePicture_dylibloader_wrapper_xrender)(Display *, Picture, unsigned long, const XRenderPictureAttributes *); +extern void (*XRenderSetPictureClipRectangles_dylibloader_wrapper_xrender)(Display *, Picture, int, int, const XRectangle *, int); +extern void (*XRenderSetPictureClipRegion_dylibloader_wrapper_xrender)(Display *, Picture, Region); +extern void (*XRenderSetPictureTransform_dylibloader_wrapper_xrender)(Display *, Picture, XTransform *); +extern void (*XRenderFreePicture_dylibloader_wrapper_xrender)(Display *, Picture); +extern void (*XRenderComposite_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, Picture, int, int, int, int, int, int, unsigned int, unsigned int); +extern GlyphSet (*XRenderCreateGlyphSet_dylibloader_wrapper_xrender)(Display *, const XRenderPictFormat *); +extern GlyphSet (*XRenderReferenceGlyphSet_dylibloader_wrapper_xrender)(Display *, GlyphSet); +extern void (*XRenderFreeGlyphSet_dylibloader_wrapper_xrender)(Display *, GlyphSet); +extern void (*XRenderAddGlyphs_dylibloader_wrapper_xrender)(Display *, GlyphSet, const Glyph *, const XGlyphInfo *, int, const char *, int); +extern void (*XRenderFreeGlyphs_dylibloader_wrapper_xrender)(Display *, GlyphSet, const Glyph *, int); +extern void (*XRenderCompositeString8_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, GlyphSet, int, int, int, int, const char *, int); +extern void (*XRenderCompositeString16_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, GlyphSet, int, int, int, int, const unsigned short *, int); +extern void (*XRenderCompositeString32_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, GlyphSet, int, int, int, int, const unsigned int *, int); +extern void (*XRenderCompositeText8_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, int, int, const XGlyphElt8 *, int); +extern void (*XRenderCompositeText16_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, int, int, const XGlyphElt16 *, int); +extern void (*XRenderCompositeText32_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, int, int, const XGlyphElt32 *, int); +extern void (*XRenderFillRectangle_dylibloader_wrapper_xrender)(Display *, int, Picture, const XRenderColor *, int, int, unsigned int, unsigned int); +extern void (*XRenderFillRectangles_dylibloader_wrapper_xrender)(Display *, int, Picture, const XRenderColor *, const XRectangle *, int); +extern void (*XRenderCompositeTrapezoids_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, const XTrapezoid *, int); +extern void (*XRenderCompositeTriangles_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, const XTriangle *, int); +extern void (*XRenderCompositeTriStrip_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, const XPointFixed *, int); +extern void (*XRenderCompositeTriFan_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, const XPointFixed *, int); +extern void (*XRenderCompositeDoublePoly_dylibloader_wrapper_xrender)(Display *, int, Picture, Picture, const XRenderPictFormat *, int, int, int, int, const XPointDouble *, int, int); +extern int (*XRenderParseColor_dylibloader_wrapper_xrender)(Display *, char *, XRenderColor *); +extern Cursor (*XRenderCreateCursor_dylibloader_wrapper_xrender)(Display *, Picture, unsigned int, unsigned int); +extern XFilters *(*XRenderQueryFilters_dylibloader_wrapper_xrender)(Display *, Drawable); +extern void (*XRenderSetPictureFilter_dylibloader_wrapper_xrender)(Display *, Picture, const char *, XFixed *, int); +extern Cursor (*XRenderCreateAnimCursor_dylibloader_wrapper_xrender)(Display *, int, XAnimCursor *); +extern void (*XRenderAddTraps_dylibloader_wrapper_xrender)(Display *, Picture, int, int, const XTrap *, int); +extern Picture (*XRenderCreateSolidFill_dylibloader_wrapper_xrender)(Display *, const XRenderColor *); +extern Picture (*XRenderCreateLinearGradient_dylibloader_wrapper_xrender)(Display *, const XLinearGradient *, const XFixed *, const XRenderColor *, int); +extern Picture (*XRenderCreateRadialGradient_dylibloader_wrapper_xrender)(Display *, const XRadialGradient *, const XFixed *, const XRenderColor *, int); +extern Picture (*XRenderCreateConicalGradient_dylibloader_wrapper_xrender)(Display *, const XConicalGradient *, const XFixed *, const XRenderColor *, int); int initialize_xrender(int verbose); #ifdef __cplusplus } diff --git a/platform/macos/SCsub b/platform/macos/SCsub index 3924e79fb6..598444ae24 100644 --- a/platform/macos/SCsub +++ b/platform/macos/SCsub @@ -27,7 +27,9 @@ def generate_bundle(target, source, env): target_bin = lipo(bin_dir + "/" + prefix, env.extra_suffix + env.module_version_string) # Assemble .app bundle and update version info. - app_dir = Dir("#bin/" + (prefix + env.extra_suffix + env.module_version_string).replace(".", "_") + ".app").abspath + app_dir = Dir( + "#bin/" + (prefix + env.extra_suffix + env.module_version_string).replace(".", "_") + ".app" + ).abspath templ = Dir("#misc/dist/macos_tools.app").abspath if os.path.exists(app_dir): shutil.rmtree(app_dir) diff --git a/platform/macos/os_macos.h b/platform/macos/os_macos.h index 303fc112bf..4fb4507837 100644 --- a/platform/macos/os_macos.h +++ b/platform/macos/os_macos.h @@ -114,6 +114,8 @@ public: virtual String get_unique_id() const override; virtual String get_processor_name() const override; + virtual String get_model_name() const override; + virtual bool is_sandboxed() const override; virtual Vector<String> get_granted_permissions() const override; virtual void revoke_granted_permissions() override; diff --git a/platform/macos/os_macos.mm b/platform/macos/os_macos.mm index d9086b8c38..08ff391aab 100644 --- a/platform/macos/os_macos.mm +++ b/platform/macos/os_macos.mm @@ -67,6 +67,15 @@ void OS_MacOS::initialize() { initialize_core(); } +String OS_MacOS::get_model_name() const { + char buffer[256]; + size_t buffer_len = 256; + if (sysctlbyname("hw.model", &buffer, &buffer_len, nullptr, 0) == 0 && buffer_len != 0) { + return String::utf8(buffer, buffer_len); + } + return OS_Unix::get_model_name(); +} + String OS_MacOS::get_processor_name() const { char buffer[256]; size_t buffer_len = 256; diff --git a/platform/web/detect.py b/platform/web/detect.py index 26bbbccffa..25a5bbe5a5 100644 --- a/platform/web/detect.py +++ b/platform/web/detect.py @@ -201,7 +201,7 @@ def configure(env: "SConsEnvironment"): sys.exit(255) env.Prepend(CPPPATH=["#platform/web"]) - env.Append(CPPDEFINES=["WEB_ENABLED", "UNIX_ENABLED"]) + env.Append(CPPDEFINES=["WEB_ENABLED", "UNIX_ENABLED", "UNIX_SOCKET_UNAVAILABLE"]) if env["opengl3"]: env.AppendUnique(CPPDEFINES=["GLES3_ENABLED"]) diff --git a/platform/web/doc_classes/EditorExportPlatformWeb.xml b/platform/web/doc_classes/EditorExportPlatformWeb.xml index 755308de9a..955e3a0232 100644 --- a/platform/web/doc_classes/EditorExportPlatformWeb.xml +++ b/platform/web/doc_classes/EditorExportPlatformWeb.xml @@ -60,15 +60,15 @@ </member> <member name="progressive_web_app/icon_144x144" type="String" setter="" getter=""> File path to the smallest icon for this web application. If not defined, defaults to the project icon. - [b]Note:[/b] If the icon is not 144x144, it will be automatically resized for the final build. + [b]Note:[/b] If the icon is not 144×144, it will be automatically resized for the final build. </member> <member name="progressive_web_app/icon_180x180" type="String" setter="" getter=""> File path to the small icon for this web application. If not defined, defaults to the project icon. - [b]Note:[/b] If the icon is not 180x180, it will be automatically resized for the final build. + [b]Note:[/b] If the icon is not 180×180, it will be automatically resized for the final build. </member> <member name="progressive_web_app/icon_512x512" type="String" setter="" getter=""> - File path to the smallest icon for this web application. If not defined, defaults to the project icon. - [b]Note:[/b] If the icon is not 512x512, it will be automatically resized for the final build. + File path to the largest icon for this web application. If not defined, defaults to the project icon. + [b]Note:[/b] If the icon is not 512×512, it will be automatically resized for the final build. </member> <member name="progressive_web_app/offline_page" type="String" setter="" getter=""> The page to display, should the server hosting the page not be available. This page is saved in the client's machine. diff --git a/platform/web/export/export_plugin.cpp b/platform/web/export/export_plugin.cpp index efe3c95496..a6835a28b2 100644 --- a/platform/web/export/export_plugin.cpp +++ b/platform/web/export/export_plugin.cpp @@ -169,6 +169,7 @@ void EditorExportPlatformWeb::_fix_html(Vector<uint8_t> &p_html, const Ref<Edito replaces["$GODOT_PROJECT_NAME"] = GLOBAL_GET("application/config/name"); replaces["$GODOT_HEAD_INCLUDE"] = head_include + custom_head_include; replaces["$GODOT_CONFIG"] = str_config; + replaces["$GODOT_SPLASH_COLOR"] = "#" + Color(GLOBAL_GET("application/boot_splash/bg_color")).to_html(false); replaces["$GODOT_SPLASH"] = p_name + ".png"; if (p_preset->get("variant/thread_support")) { diff --git a/platform/web/js/libs/library_godot_input.js b/platform/web/js/libs/library_godot_input.js index 6e3b97023d..8134631f1b 100644 --- a/platform/web/js/libs/library_godot_input.js +++ b/platform/web/js/libs/library_godot_input.js @@ -38,41 +38,57 @@ const GodotIME = { $GodotIME: { ime: null, active: false, + focusTimerIntervalId: -1, getModifiers: function (evt) { return (evt.shiftKey + 0) + ((evt.altKey + 0) << 1) + ((evt.ctrlKey + 0) << 2) + ((evt.metaKey + 0) << 3); }, ime_active: function (active) { - function focus_timer() { - GodotIME.active = true; - GodotIME.ime.focus(); + function clearFocusTimerInterval() { + clearInterval(GodotIME.focusTimerIntervalId); + GodotIME.focusTimerIntervalId = -1; } - if (GodotIME.ime) { - if (active) { - GodotIME.ime.style.display = 'block'; - setInterval(focus_timer, 100); - } else { - GodotIME.ime.style.display = 'none'; - GodotConfig.canvas.focus(); - GodotIME.active = false; + function focusTimer() { + if (GodotIME.ime == null) { + clearFocusTimerInterval(); + return; } + GodotIME.ime.focus(); + } + + if (GodotIME.focusTimerIntervalId > -1) { + clearFocusTimerInterval(); + } + + if (GodotIME.ime == null) { + return; + } + + GodotIME.active = active; + if (active) { + GodotIME.ime.style.display = 'block'; + GodotIME.focusTimerIntervalId = setInterval(focusTimer, 100); + } else { + GodotIME.ime.style.display = 'none'; + GodotConfig.canvas.focus(); } }, ime_position: function (x, y) { - if (GodotIME.ime) { - const canvas = GodotConfig.canvas; - const rect = canvas.getBoundingClientRect(); - const rw = canvas.width / rect.width; - const rh = canvas.height / rect.height; - const clx = (x / rw) + rect.x; - const cly = (y / rh) + rect.y; - - GodotIME.ime.style.left = `${clx}px`; - GodotIME.ime.style.top = `${cly}px`; + if (GodotIME.ime == null) { + return; } + const canvas = GodotConfig.canvas; + const rect = canvas.getBoundingClientRect(); + const rw = canvas.width / rect.width; + const rh = canvas.height / rect.height; + const clx = (x / rw) + rect.x; + const cly = (y / rh) + rect.y; + + GodotIME.ime.style.left = `${clx}px`; + GodotIME.ime.style.top = `${cly}px`; }, init: function (ime_cb, key_cb, code, key) { @@ -84,20 +100,27 @@ const GodotIME = { evt.preventDefault(); } function ime_event_cb(event) { - if (GodotIME.ime) { - if (event.type === 'compositionstart') { - ime_cb(0, null); - GodotIME.ime.innerHTML = ''; - } else if (event.type === 'compositionupdate') { - const ptr = GodotRuntime.allocString(event.data); - ime_cb(1, ptr); - GodotRuntime.free(ptr); - } else if (event.type === 'compositionend') { - const ptr = GodotRuntime.allocString(event.data); - ime_cb(2, ptr); - GodotRuntime.free(ptr); - GodotIME.ime.innerHTML = ''; - } + if (GodotIME.ime == null) { + return; + } + switch (event.type) { + case 'compositionstart': + ime_cb(0, null); + GodotIME.ime.innerHTML = ''; + break; + case 'compositionupdate': { + const ptr = GodotRuntime.allocString(event.data); + ime_cb(1, ptr); + GodotRuntime.free(ptr); + } break; + case 'compositionend': { + const ptr = GodotRuntime.allocString(event.data); + ime_cb(2, ptr); + GodotRuntime.free(ptr); + GodotIME.ime.innerHTML = ''; + } break; + default: + // Do nothing. } } @@ -133,10 +156,15 @@ const GodotIME = { }, clear: function () { - if (GodotIME.ime) { - GodotIME.ime.remove(); - GodotIME.ime = null; + if (GodotIME.ime == null) { + return; + } + if (GodotIME.focusTimerIntervalId > -1) { + clearInterval(GodotIME.focusTimerIntervalId); + GodotIME.focusTimerIntervalId = -1; } + GodotIME.ime.remove(); + GodotIME.ime = null; }, }, }; diff --git a/platform/web/package-lock.json b/platform/web/package-lock.json index a2e0fd3b27..7947fb96e4 100644 --- a/platform/web/package-lock.json +++ b/platform/web/package-lock.json @@ -9,14 +9,14 @@ "version": "1.0.0", "license": "MIT", "devDependencies": { - "@eslint/js": "^9.3.0", - "@html-eslint/eslint-plugin": "^0.24.1", - "@html-eslint/parser": "^0.24.1", - "@stylistic/eslint-plugin": "^2.1.0", - "eslint": "^9.3.0", + "@eslint/js": "^9.12.0", + "@html-eslint/eslint-plugin": "^0.27.0", + "@html-eslint/parser": "^0.27.0", + "@stylistic/eslint-plugin": "^2.9.0", + "eslint": "^9.12.0", "eslint-plugin-html": "^8.1.1", "espree": "^10.0.1", - "globals": "^15.3.0", + "globals": "^15.9.0", "jsdoc": "^4.0.3" } }, @@ -60,14 +60,40 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", + "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", @@ -104,28 +130,54 @@ } }, "node_modules/@eslint/js": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.3.0.tgz", - "integrity": "sha512-niBqk8iwv96+yuTwjM6bWg8ovzAPF9qkICsGtcoa5/dmqcEMfdwNAX7+/OHcJHc7wj7XqPxH98oAHytFYlw6Sw==", + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", + "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.1.tgz", + "integrity": "sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "levn": "^0.4.1" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@html-eslint/eslint-plugin": { - "version": "0.24.1", - "resolved": "https://registry.npmjs.org/@html-eslint/eslint-plugin/-/eslint-plugin-0.24.1.tgz", - "integrity": "sha512-JwNDQBrNIWEPcxgSpla/2jaUXyQCqL7Xp8CmON4Bk5qg8MwiDLXOgjylfVC+tN52i8JeHWMca34I9DqBGRj9Qg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@html-eslint/eslint-plugin/-/eslint-plugin-0.27.0.tgz", + "integrity": "sha512-aAF14sgDKidMCCQpJ4kIhe+fwyAaAbvDlgVTIgd99F+HOWxokTTXDt39a3gewMBo76IeEHDaoizUDJQ/Vc7Mdg==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@html-eslint/parser": { - "version": "0.24.1", - "resolved": "https://registry.npmjs.org/@html-eslint/parser/-/parser-0.24.1.tgz", - "integrity": "sha512-O13xX/+Ldh0P7VZMpDDYc3XtWiE1cYm5QhVJ0VB5i7D8Q69HrrGN+5BjS17vkCoLTz+3zWWIiJv4oFmyS5LReA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@html-eslint/parser/-/parser-0.27.0.tgz", + "integrity": "sha512-F/A1M0jnDAYoRvJiiSC7pIBD9DAsf4EhbndbvEi81aozD/wI8WWXON50xZPUaGHCI1C+2syTVifxDz8MvDKaQA==", "dev": true, + "license": "MIT", "dependencies": { "es-html-parser": "^0.0.9" }, @@ -133,18 +185,28 @@ "node": ">=8.10.0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "node_modules/@humanfs/core": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", + "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.5", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", + "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@humanfs/core": "^0.19.0", + "@humanwhocodes/retry": "^0.3.0" }, "engines": { - "node": ">=10.10.0" + "node": ">=18.18.0" } }, "node_modules/@humanwhocodes/module-importer": { @@ -160,17 +222,12 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "dev": true - }, "node_modules/@humanwhocodes/retry": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", - "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=18.18" }, @@ -227,50 +284,15 @@ } }, "node_modules/@stylistic/eslint-plugin": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.1.0.tgz", - "integrity": "sha512-cBBowKP2u/+uE5CzgH5w8pE9VKqcM7BXdIDPIbGt2rmLJGnA6MJPr9vYGaqgMoJFs7R/FzsMQerMvvEP40g2uw==", - "dev": true, - "dependencies": { - "@stylistic/eslint-plugin-js": "2.1.0", - "@stylistic/eslint-plugin-jsx": "2.1.0", - "@stylistic/eslint-plugin-plus": "2.1.0", - "@stylistic/eslint-plugin-ts": "2.1.0", - "@types/eslint": "^8.56.10" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/@stylistic/eslint-plugin-js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-2.1.0.tgz", - "integrity": "sha512-gdXUjGNSsnY6nPyqxu6lmDTtVrwCOjun4x8PUn0x04d5ucLI74N3MT1Q0UhdcOR9No3bo5PGDyBgXK+KmD787A==", - "dev": true, - "dependencies": { - "@types/eslint": "^8.56.10", - "acorn": "^8.11.3", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.0.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/@stylistic/eslint-plugin-jsx": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-2.1.0.tgz", - "integrity": "sha512-mMD7S+IndZo2vxmwpHVTCwx2O1VdtE5tmpeNwgaEcXODzWV1WTWpnsc/PECQKIr/mkLPFWiSIqcuYNhQ/3l6AQ==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.9.0.tgz", + "integrity": "sha512-OrDyFAYjBT61122MIY1a3SfEgy3YCMgt2vL4eoPmvTwDBwyQhAXurxNQznlRD/jESNfYWfID8Ej+31LljvF7Xg==", "dev": true, + "license": "MIT", "dependencies": { - "@stylistic/eslint-plugin-js": "^2.1.0", - "@types/eslint": "^8.56.10", + "@typescript-eslint/utils": "^8.8.0", + "eslint-visitor-keys": "^4.1.0", + "espree": "^10.2.0", "estraverse": "^5.3.0", "picomatch": "^4.0.2" }, @@ -281,101 +303,19 @@ "eslint": ">=8.40.0" } }, - "node_modules/@stylistic/eslint-plugin-plus": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-2.1.0.tgz", - "integrity": "sha512-S5QAlgYXESJaSBFhBSBLZy9o36gXrXQwWSt6QkO+F0SrT9vpV5JF/VKoh+ojO7tHzd8Ckmyouq02TT9Sv2B0zQ==", - "dev": true, - "dependencies": { - "@types/eslint": "^8.56.10", - "@typescript-eslint/utils": "^7.8.0" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/@stylistic/eslint-plugin-plus/node_modules/@typescript-eslint/utils": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.10.0.tgz", - "integrity": "sha512-olzif1Fuo8R8m/qKkzJqT7qwy16CzPRWBvERS0uvyc+DHd8AKbO4Jb7kpAvVzMmZm8TrHnI7hvjN4I05zow+tg==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.10.0", - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/typescript-estree": "7.10.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@stylistic/eslint-plugin-ts": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-2.1.0.tgz", - "integrity": "sha512-2ioFibufHYBALx2TBrU4KXovCkN8qCqcb9yIHc0fyOfTaO5jw4d56WW7YRcF3Zgde6qFyXwAN6z/+w4pnmos1g==", - "dev": true, - "dependencies": { - "@stylistic/eslint-plugin-js": "2.1.0", - "@types/eslint": "^8.56.10", - "@typescript-eslint/utils": "^7.8.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/@stylistic/eslint-plugin-ts/node_modules/@typescript-eslint/utils": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.10.0.tgz", - "integrity": "sha512-olzif1Fuo8R8m/qKkzJqT7qwy16CzPRWBvERS0uvyc+DHd8AKbO4Jb7kpAvVzMmZm8TrHnI7hvjN4I05zow+tg==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.10.0", - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/typescript-estree": "7.10.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/linkify-it": { "version": "5.0.0", @@ -400,16 +340,17 @@ "dev": true }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.10.0.tgz", - "integrity": "sha512-7L01/K8W/VGl7noe2mgH0K7BE29Sq6KAbVmxurj8GGaPDZXPr8EEQ2seOeAS+mEV9DnzxBQB6ax6qQQ5C6P4xg==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.11.0.tgz", + "integrity": "sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0" + "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/visitor-keys": "8.11.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -417,12 +358,13 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.10.0.tgz", - "integrity": "sha512-7fNj+Ya35aNyhuqrA1E/VayQX9Elwr8NKZ4WueClR3KwJ7Xx9jcCdOrLW04h51de/+gNbyFMs+IDxh5xIwfbNg==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.11.0.tgz", + "integrity": "sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw==", "dev": true, + "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -430,22 +372,23 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.10.0.tgz", - "integrity": "sha512-LXFnQJjL9XIcxeVfqmNj60YhatpRLt6UhdlFwAkjNc6jSUlK8zQOl1oktAP8PlWFzPQC1jny/8Bai3/HPuvN5g==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.11.0.tgz", + "integrity": "sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.10.0", - "@typescript-eslint/visitor-keys": "7.10.0", + "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/visitor-keys": "8.11.0", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -462,15 +405,17 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -481,17 +426,41 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@typescript-eslint/utils": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.11.0.tgz", + "integrity": "sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.11.0", + "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/typescript-estree": "8.11.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.10.0.tgz", - "integrity": "sha512-9ntIVgsi6gg6FIq9xjEO4VQJvwOqA3jaBFQJ/6TK5AvEup2+cECI6Fh7QiBxmfMHXU0V0J4RyPeOU1VDNzl9cg==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.11.0.tgz", + "integrity": "sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.10.0", + "@typescript-eslint/types": "8.11.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -503,6 +472,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -511,10 +481,11 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -547,15 +518,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -577,15 +539,6 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -613,6 +566,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -718,18 +672,6 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -816,28 +758,33 @@ } }, "node_modules/eslint": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.3.0.tgz", - "integrity": "sha512-5Iv4CsZW030lpUqHBapdPo3MJetAPtejVW8B84GIcIIv8+ohFaddXsrn1Gn8uD9ijDb+kcYKFUVmC8qG8B2ORQ==", + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.12.0.tgz", + "integrity": "sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.6.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.3.0", - "@humanwhocodes/config-array": "^0.13.0", + "@eslint/js": "9.12.0", + "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.5", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.0", - "@nodelib/fs.walk": "^1.2.8", + "@humanwhocodes/retry": "^0.3.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.1", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.0.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.1.0", + "eslint-visitor-keys": "^4.1.0", + "espree": "^10.2.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", @@ -846,14 +793,11 @@ "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": { @@ -863,7 +807,15 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-plugin-html": { @@ -879,10 +831,11 @@ } }, "node_modules/eslint-scope": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.1.tgz", - "integrity": "sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", + "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -895,10 +848,11 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", + "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -907,14 +861,15 @@ } }, "node_modules/espree": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.0.1.tgz", - "integrity": "sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", + "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.11.3", + "acorn": "^8.12.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" + "eslint-visitor-keys": "^4.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -940,6 +895,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -976,6 +932,7 @@ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -992,6 +949,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -1037,6 +995,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -1092,10 +1051,11 @@ } }, "node_modules/globals": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.3.0.tgz", - "integrity": "sha512-cCdyVjIUVTtX8ZsPkq1oCsOsLmGIswqnjZYMJJTGaNApj1yHtLSymKhwH51ttirREn75z3p4k051clwg7rvNKA==", + "version": "15.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz", + "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -1103,26 +1063,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -1217,19 +1157,11 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1430,15 +1362,17 @@ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -1452,6 +1386,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -1572,20 +1507,12 @@ "node": ">=8" } }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/picomatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -1692,10 +1619,11 @@ } }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -1724,27 +1652,6 @@ "node": ">=8" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -1780,6 +1687,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -1792,6 +1700,7 @@ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -1812,10 +1721,11 @@ } }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, + "license": "Apache-2.0", "peer": true, "bin": { "tsc": "bin/tsc", diff --git a/platform/web/package.json b/platform/web/package.json index 588af2ff3b..bf61eb184c 100644 --- a/platform/web/package.json +++ b/platform/web/package.json @@ -11,14 +11,14 @@ "format": "npm run lint -- --fix" }, "devDependencies": { - "@eslint/js": "^9.3.0", - "@html-eslint/eslint-plugin": "^0.24.1", - "@html-eslint/parser": "^0.24.1", - "@stylistic/eslint-plugin": "^2.1.0", - "eslint": "^9.3.0", + "@eslint/js": "^9.12.0", + "@html-eslint/eslint-plugin": "^0.27.0", + "@html-eslint/parser": "^0.27.0", + "@stylistic/eslint-plugin": "^2.9.0", + "eslint": "^9.12.0", "eslint-plugin-html": "^8.1.1", "espree": "^10.0.1", - "globals": "^15.3.0", + "globals": "^15.9.0", "jsdoc": "^4.0.3" } } diff --git a/platform/windows/SCsub b/platform/windows/SCsub index 30df9df809..1ddefb9c33 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -60,6 +60,9 @@ sources += res_obj prog = env.add_program("#bin/godot", sources, PROGSUFFIX=env["PROGSUFFIX"]) arrange_program_clean(prog) +if env.msvc: + env.Depends(prog, "godot.natvis") + # Build console wrapper app. if env["windows_subsystem"] == "gui": env_wrap = env.Clone() @@ -80,16 +83,6 @@ if env["windows_subsystem"] == "gui": env_wrap.Depends(prog_wrap, prog) sources += common_win_wrap + res_wrap_obj -# Microsoft Visual Studio Project Generation -if env["vsproj"]: - env.vs_srcs += ["platform/windows/" + res_file] - env.vs_srcs += ["platform/windows/godot.natvis"] - for x in common_win: - env.vs_srcs += ["platform/windows/" + str(x)] - if env["windows_subsystem"] == "gui": - for x in common_win_wrap: - env.vs_srcs += ["platform/windows/" + str(x)] - if env["d3d12"]: dxc_target_aliases = { "x86_32": "x86", diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index a6eab1bd29..26dad095ad 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -4792,9 +4792,12 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA break; } - DisplayServer::WindowID receiving_window_id = _get_focused_window_or_popup(); - if (receiving_window_id == INVALID_WINDOW_ID) { - receiving_window_id = window_id; + DisplayServer::WindowID receiving_window_id = window_id; + if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { + receiving_window_id = _get_focused_window_or_popup(); + if (receiving_window_id == INVALID_WINDOW_ID) { + receiving_window_id = window_id; + } } const BitField<WinKeyModifierMask> &mods = _get_mods(); diff --git a/platform/windows/godot.natvis b/platform/windows/godot.natvis index fc34ad3cb3..e3a535580f 100644 --- a/platform/windows/godot.natvis +++ b/platform/windows/godot.natvis @@ -30,16 +30,6 @@ </Expand> </Type> - <Type Name="TypedArray<*>"> - <Expand> - <Item Name="[size]"> _p->array._cowdata._ptr ? (((const unsigned long long *)(_p->array._cowdata._ptr))[-1]) : 0</Item> - <ArrayItems> - <Size>_p->array._cowdata._ptr ? (((const unsigned long long *)(_p->array._cowdata._ptr))[-1]) : 0</Size> - <ValuePointer >(Variant *) _p->array._cowdata._ptr</ValuePointer> - </ArrayItems> - </Expand> - </Type> - <Type Name="Dictionary"> <Expand> <Item Name="[size]">_p && _p->variant_map.head_element ? _p->variant_map.num_elements : 0</Item> @@ -153,7 +143,7 @@ <Type Name="HashMapElement<*,*>" IncludeView="MapHelper"> <DisplayString>{data.value}</DisplayString> <Expand> - <Item Name="[key]" >($T1 *) &data.key</Item> + <Item Name="[key]">($T1 *) &data.key</Item> <Item Name="[value]">($T2 *) &data.value</Item> </Expand> </Type> @@ -285,39 +275,164 @@ </Type> <Type Name="Vector2"> - <DisplayString>{{{x},{y}}}</DisplayString> + <DisplayString>({x,g}, {y,g})</DisplayString> + <Expand> + <Item Name="[x]">x</Item> + <Item Name="[y]">y</Item> + </Expand> + </Type> + <Type Name="Vector2i"> + <DisplayString>({x}, {y})</DisplayString> <Expand> - <Item Name="x">x</Item> - <Item Name="y">y</Item> + <Item Name="[x]">x</Item> + <Item Name="[y]">y</Item> </Expand> </Type> <Type Name="Vector3"> - <DisplayString>{{{x},{y},{z}}}</DisplayString> + <DisplayString>({x,g}, {y,g}, {z,g})</DisplayString> + <Expand> + <Item Name="[x]">x</Item> + <Item Name="[y]">y</Item> + <Item Name="[z]">z</Item> + </Expand> + </Type> + <Type Name="Vector3i"> + <DisplayString>({x}, {y}, {z})</DisplayString> <Expand> - <Item Name="x">x</Item> - <Item Name="y">y</Item> - <Item Name="z">z</Item> + <Item Name="[x]">x</Item> + <Item Name="[y]">y</Item> + <Item Name="[z]">z</Item> + </Expand> + </Type> + + <Type Name="Vector4"> + <DisplayString>({x,g}, {y,g}, {z,g}, {w,g})</DisplayString> + <Expand> + <Item Name="[x]">x</Item> + <Item Name="[y]">y</Item> + <Item Name="[z]">z</Item> + <Item Name="[w]">w</Item> + </Expand> + </Type> + <Type Name="Vector4i"> + <DisplayString>({x}, {y}, {z}, {w})</DisplayString> + <Expand> + <Item Name="[x]">x</Item> + <Item Name="[y]">y</Item> + <Item Name="[z]">z</Item> + <Item Name="[w]">w</Item> </Expand> </Type> <Type Name="Quaternion"> - <DisplayString>Quaternion {{{x},{y},{z},{w}}}</DisplayString> + <DisplayString>({x,g}, {y,g}, {z,g}, {w,g})</DisplayString> <Expand> - <Item Name="x">x</Item> - <Item Name="y">y</Item> - <Item Name="z">z</Item> - <Item Name="w">w</Item> + <Item Name="[x]">x</Item> + <Item Name="[y]">y</Item> + <Item Name="[z]">z</Item> + <Item Name="[w]">w</Item> </Expand> </Type> <Type Name="Color"> - <DisplayString>Color {{{r},{g},{b},{a}}}</DisplayString> + <DisplayString>({r,g}, {g,g}, {b,g}, {a,g})</DisplayString> + <Expand> + <Item Name="[red]">r</Item> + <Item Name="[green]">g</Item> + <Item Name="[blue]">b</Item> + <Item Name="[alpha]">a</Item> + </Expand> + </Type> + + <Type Name="Rect2"> + <DisplayString>[P: {position}, S: {size}]</DisplayString> + <Expand> + <Item Name="[position]">position,nr</Item> + <Item Name="[size]">size,nr</Item> + </Expand> + </Type> + <Type Name="Rect2i"> + <DisplayString>[P: {position}, S: {size}]</DisplayString> + <Expand> + <Item Name="[position]">position,nr</Item> + <Item Name="[size]">size,nr</Item> + </Expand> + </Type> + + <Type Name="AABB"> + <DisplayString>[P: {position}, S: {size}]</DisplayString> + <Expand> + <Item Name="[position]">position,nr</Item> + <Item Name="[size]">size,nr</Item> + </Expand> + </Type> + + <Type Name="Plane"> + <DisplayString>[N: {normal}, D: {d,g}]</DisplayString> + <Expand> + <Item Name="[normal]">normal,nr</Item> + <Item Name="[d]">d</Item> + </Expand> + </Type> + + <Type Name="Basis"> + <DisplayString>[X: {rows[0]}, Y: {rows[1]}, Z: {rows[2]}]</DisplayString> + <Expand> + <Item Name="[x]">rows[0],nr</Item> + <Item Name="[y]">rows[1],nr</Item> + <Item Name="[z]">rows[2],nr</Item> + </Expand> + </Type> + + <Type Name="Transform2D"> + <DisplayString>[X: {columns[0]}, Y: {columns[1]}, O: {columns[2]}]</DisplayString> + <Expand> + <Item Name="[x]">columns[0],nr</Item> + <Item Name="[y]">columns[1],nr</Item> + <Item Name="[origin]">columns[2],nr</Item> + </Expand> + </Type> + + <Type Name="Transform3D"> + <!-- Can't call column functions, so just pretend we can via obscene code duplication. --> + <DisplayString>[X: ({basis.rows[0].x,g}, {basis.rows[1].x,g}, {basis.rows[2].x,g}), Y: ({basis.rows[0].y,g}, {basis.rows[1].y,g}, {basis.rows[2].y,g}), Z: ({basis.rows[0].z,g}, {basis.rows[1].z,g}, {basis.rows[2].z,g}), O: {origin}]</DisplayString> + <Expand> + <Synthetic Name="[x]"> + <DisplayString>({basis.rows[0].x,g}, {basis.rows[1].x,g}, {basis.rows[2].x,g})</DisplayString> + <Expand> + <Item Name="[x]">basis.rows[0].x</Item> + <Item Name="[y]">basis.rows[1].x</Item> + <Item Name="[z]">basis.rows[2].x</Item> + </Expand> + </Synthetic> + <Synthetic Name="[y]"> + <DisplayString>({basis.rows[0].y,g}, {basis.rows[1].y,g}, {basis.rows[2].y,g})</DisplayString> + <Expand> + <Item Name="[x]">basis.rows[0].y</Item> + <Item Name="[y]">basis.rows[1].y</Item> + <Item Name="[z]">basis.rows[2].y</Item> + </Expand> + </Synthetic> + <Synthetic Name="[z]"> + <DisplayString>({basis.rows[0].z,g}, {basis.rows[1].z,g}, {basis.rows[2].z,g})</DisplayString> + <Expand> + <Item Name="[x]">basis.rows[0].z</Item> + <Item Name="[y]">basis.rows[1].z</Item> + <Item Name="[z]">basis.rows[2].z</Item> + </Expand> + </Synthetic> + <Item Name="[origin]">origin,nr</Item> + </Expand> + </Type> + + <Type Name="Projection"> + <DisplayString>[X: {columns[0]}, Y: {columns[1]}, Z: {columns[2]}, W: {columns[3]}]</DisplayString> <Expand> - <Item Name="red">r</Item> - <Item Name="green">g</Item> - <Item Name="blue">b</Item> - <Item Name="alpha">a</Item> + <Item Name="[x]">columns[0],nr</Item> + <Item Name="[y]">columns[1],nr</Item> + <Item Name="[z]">columns[2],nr</Item> + <Item Name="[w]">columns[3],nr</Item> </Expand> </Type> </AutoVisualizer> diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index bff3443214..4d253059b2 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -40,10 +40,10 @@ #include "core/debugger/script_debugger.h" #include "core/io/marshalls.h" #include "core/version_generated.gen.h" -#include "drivers/unix/net_socket_posix.h" #include "drivers/windows/dir_access_windows.h" #include "drivers/windows/file_access_windows.h" #include "drivers/windows/file_access_windows_pipe.h" +#include "drivers/windows/net_socket_winsock.h" #include "main/main.h" #include "servers/audio_server.h" #include "servers/rendering/rendering_server_default.h" @@ -156,6 +156,52 @@ void RedirectIOToConsole() { } } +bool OS_Windows::is_using_con_wrapper() const { + static String exe_renames[] = { + ".console.exe", + "_console.exe", + " console.exe", + "console.exe", + String(), + }; + + bool found_exe = false; + bool found_conwrap_exe = false; + String exe_name = get_executable_path().to_lower(); + String exe_dir = exe_name.get_base_dir(); + String exe_fname = exe_name.get_file().get_basename(); + + DWORD pids[256]; + DWORD count = GetConsoleProcessList(&pids[0], 256); + for (DWORD i = 0; i < count; i++) { + HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, pids[i]); + if (process != NULL) { + WCHAR proc_name[MAX_PATH]; + DWORD len = MAX_PATH; + if (QueryFullProcessImageNameW(process, 0, &proc_name[0], &len)) { + String name = String::utf16((const char16_t *)&proc_name[0], len).replace("\\", "/").to_lower(); + if (name == exe_name) { + found_exe = true; + } + for (int j = 0; !exe_renames[j].is_empty(); j++) { + if (name == exe_dir.path_join(exe_fname + exe_renames[j])) { + found_conwrap_exe = true; + } + } + } + CloseHandle(process); + if (found_conwrap_exe && found_exe) { + break; + } + } + } + if (!found_exe) { + return true; // Unable to read console info, assume true. + } + + return found_conwrap_exe; +} + BOOL WINAPI HandlerRoutine(_In_ DWORD dwCtrlType) { if (!EngineDebugger::is_active()) { return FALSE; @@ -209,7 +255,7 @@ void OS_Windows::initialize() { DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_USERDATA); DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM); - NetSocketPosix::make_default(); + NetSocketWinSock::make_default(); // We need to know how often the clock is updated QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second); @@ -303,7 +349,7 @@ void OS_Windows::finalize_core() { timeEndPeriod(1); memdelete(process_map); - NetSocketPosix::cleanup(); + NetSocketWinSock::cleanup(); #ifdef WINDOWS_DEBUG_OUTPUT_ENABLED remove_error_handler(&error_handlers); @@ -918,18 +964,10 @@ Dictionary OS_Windows::execute_with_pipe(const String &p_path, const List<String sa.lpSecurityDescriptor = nullptr; ERR_FAIL_COND_V(!CreatePipe(&pipe_in[0], &pipe_in[1], &sa, 0), ret); - if (!SetHandleInformation(pipe_in[1], HANDLE_FLAG_INHERIT, 0)) { - CLEAN_PIPES - ERR_FAIL_V(ret); - } if (!CreatePipe(&pipe_out[0], &pipe_out[1], &sa, 0)) { CLEAN_PIPES ERR_FAIL_V(ret); } - if (!SetHandleInformation(pipe_out[0], HANDLE_FLAG_INHERIT, 0)) { - CLEAN_PIPES - ERR_FAIL_V(ret); - } if (!CreatePipe(&pipe_err[0], &pipe_err[1], &sa, 0)) { CLEAN_PIPES ERR_FAIL_V(ret); @@ -939,16 +977,37 @@ Dictionary OS_Windows::execute_with_pipe(const String &p_path, const List<String // Create process. ProcessInfo pi; ZeroMemory(&pi.si, sizeof(pi.si)); - pi.si.cb = sizeof(pi.si); + pi.si.StartupInfo.cb = sizeof(pi.si); ZeroMemory(&pi.pi, sizeof(pi.pi)); - LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si; + LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si.StartupInfo; - pi.si.dwFlags |= STARTF_USESTDHANDLES; - pi.si.hStdInput = pipe_in[0]; - pi.si.hStdOutput = pipe_out[1]; - pi.si.hStdError = pipe_err[1]; + pi.si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES; + pi.si.StartupInfo.hStdInput = pipe_in[0]; + pi.si.StartupInfo.hStdOutput = pipe_out[1]; + pi.si.StartupInfo.hStdError = pipe_err[1]; - DWORD creation_flags = NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW; + size_t attr_list_size = 0; + InitializeProcThreadAttributeList(nullptr, 1, 0, &attr_list_size); + pi.si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)alloca(attr_list_size); + if (!InitializeProcThreadAttributeList(pi.si.lpAttributeList, 1, 0, &attr_list_size)) { + CLEAN_PIPES + ERR_FAIL_V(ret); + } + HANDLE handles_to_inherit[] = { pipe_in[0], pipe_out[1], pipe_err[1] }; + if (!UpdateProcThreadAttribute( + pi.si.lpAttributeList, + 0, + PROC_THREAD_ATTRIBUTE_HANDLE_LIST, + handles_to_inherit, + sizeof(handles_to_inherit), + nullptr, + nullptr)) { + CLEAN_PIPES + DeleteProcThreadAttributeList(pi.si.lpAttributeList); + ERR_FAIL_V(ret); + } + + DWORD creation_flags = NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | EXTENDED_STARTUPINFO_PRESENT; Char16String current_dir_name; size_t str_len = GetCurrentDirectoryW(0, nullptr); @@ -964,11 +1023,13 @@ Dictionary OS_Windows::execute_with_pipe(const String &p_path, const List<String if (!CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, true, creation_flags, nullptr, (LPWSTR)current_dir_name.ptr(), si_w, &pi.pi)) { CLEAN_PIPES + DeleteProcThreadAttributeList(pi.si.lpAttributeList); ERR_FAIL_V_MSG(ret, "Could not create child process: " + command); } CloseHandle(pipe_in[0]); CloseHandle(pipe_out[1]); CloseHandle(pipe_err[1]); + DeleteProcThreadAttributeList(pi.si.lpAttributeList); ProcessID pid = pi.pi.dwProcessId; process_map_mutex.lock(); @@ -1000,9 +1061,9 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, ProcessInfo pi; ZeroMemory(&pi.si, sizeof(pi.si)); - pi.si.cb = sizeof(pi.si); + pi.si.StartupInfo.cb = sizeof(pi.si); ZeroMemory(&pi.pi, sizeof(pi.pi)); - LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si; + LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si.StartupInfo; bool inherit_handles = false; HANDLE pipe[2] = { nullptr, nullptr }; @@ -1014,16 +1075,40 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, sa.lpSecurityDescriptor = nullptr; ERR_FAIL_COND_V(!CreatePipe(&pipe[0], &pipe[1], &sa, 0), ERR_CANT_FORK); - ERR_FAIL_COND_V(!SetHandleInformation(pipe[0], HANDLE_FLAG_INHERIT, 0), ERR_CANT_FORK); // Read handle is for host process only and should not be inherited. - pi.si.dwFlags |= STARTF_USESTDHANDLES; - pi.si.hStdOutput = pipe[1]; + pi.si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES; + pi.si.StartupInfo.hStdOutput = pipe[1]; if (read_stderr) { - pi.si.hStdError = pipe[1]; + pi.si.StartupInfo.hStdError = pipe[1]; + } + + size_t attr_list_size = 0; + InitializeProcThreadAttributeList(nullptr, 1, 0, &attr_list_size); + pi.si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)alloca(attr_list_size); + if (!InitializeProcThreadAttributeList(pi.si.lpAttributeList, 1, 0, &attr_list_size)) { + CloseHandle(pipe[0]); // Cleanup pipe handles. + CloseHandle(pipe[1]); + ERR_FAIL_V(ERR_CANT_FORK); + } + if (!UpdateProcThreadAttribute( + pi.si.lpAttributeList, + 0, + PROC_THREAD_ATTRIBUTE_HANDLE_LIST, + &pipe[1], + sizeof(HANDLE), + nullptr, + nullptr)) { + CloseHandle(pipe[0]); // Cleanup pipe handles. + CloseHandle(pipe[1]); + DeleteProcThreadAttributeList(pi.si.lpAttributeList); + ERR_FAIL_V(ERR_CANT_FORK); } inherit_handles = true; } DWORD creation_flags = NORMAL_PRIORITY_CLASS; + if (inherit_handles) { + creation_flags |= EXTENDED_STARTUPINFO_PRESENT; + } if (p_open_console) { creation_flags |= CREATE_NEW_CONSOLE; } else { @@ -1046,6 +1131,7 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, if (!ret && r_pipe) { CloseHandle(pipe[0]); // Cleanup pipe handles. CloseHandle(pipe[1]); + DeleteProcThreadAttributeList(pi.si.lpAttributeList); } ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command); @@ -1101,6 +1187,9 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, CloseHandle(pi.pi.hProcess); CloseHandle(pi.pi.hThread); + if (r_pipe) { + DeleteProcThreadAttributeList(pi.si.lpAttributeList); + } return OK; } @@ -1114,9 +1203,9 @@ Error OS_Windows::create_process(const String &p_path, const List<String> &p_arg ProcessInfo pi; ZeroMemory(&pi.si, sizeof(pi.si)); - pi.si.cb = sizeof(pi.si); + pi.si.StartupInfo.cb = sizeof(pi.si.StartupInfo); ZeroMemory(&pi.pi, sizeof(pi.pi)); - LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si; + LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si.StartupInfo; DWORD creation_flags = NORMAL_PRIORITY_CLASS; if (p_open_console) { @@ -1639,16 +1728,115 @@ void OS_Windows::unset_environment(const String &p_var) const { SetEnvironmentVariableW((LPCWSTR)(p_var.utf16().get_data()), nullptr); // Null to delete. } -String OS_Windows::get_stdin_string() { - char buff[1024]; +String OS_Windows::get_stdin_string(int64_t p_buffer_size) { + if (get_stdin_type() == STD_HANDLE_INVALID) { + return String(); + } + + Vector<uint8_t> data; + data.resize(p_buffer_size); DWORD count = 0; - if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buff, 1024, &count, nullptr)) { - return String::utf8((const char *)buff, count); + if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), data.ptrw(), data.size(), &count, nullptr)) { + return String::utf8((const char *)data.ptr(), count); } return String(); } +PackedByteArray OS_Windows::get_stdin_buffer(int64_t p_buffer_size) { + Vector<uint8_t> data; + data.resize(p_buffer_size); + DWORD count = 0; + if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), data.ptrw(), data.size(), &count, nullptr)) { + return data; + } + + return PackedByteArray(); +} + +OS_Windows::StdHandleType OS_Windows::get_stdin_type() const { + HANDLE h = GetStdHandle(STD_INPUT_HANDLE); + if (h == 0 || h == INVALID_HANDLE_VALUE) { + return STD_HANDLE_INVALID; + } + DWORD ftype = GetFileType(h); + if (ftype == FILE_TYPE_UNKNOWN && GetLastError() != ERROR_SUCCESS) { + return STD_HANDLE_UNKNOWN; + } + ftype &= ~(FILE_TYPE_REMOTE); + + if (ftype == FILE_TYPE_DISK) { + return STD_HANDLE_FILE; + } else if (ftype == FILE_TYPE_PIPE) { + return STD_HANDLE_PIPE; + } else { + DWORD conmode = 0; + BOOL res = GetConsoleMode(h, &conmode); + if (!res && (GetLastError() == ERROR_INVALID_HANDLE)) { + return STD_HANDLE_UNKNOWN; // Unknown character device. + } else { +#ifndef WINDOWS_SUBSYSTEM_CONSOLE + if (!is_using_con_wrapper()) { + return STD_HANDLE_INVALID; // Window app can't read stdin input without werapper. + } +#endif + return STD_HANDLE_CONSOLE; + } + } +} + +OS_Windows::StdHandleType OS_Windows::get_stdout_type() const { + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + if (h == 0 || h == INVALID_HANDLE_VALUE) { + return STD_HANDLE_INVALID; + } + DWORD ftype = GetFileType(h); + if (ftype == FILE_TYPE_UNKNOWN && GetLastError() != ERROR_SUCCESS) { + return STD_HANDLE_UNKNOWN; + } + ftype &= ~(FILE_TYPE_REMOTE); + + if (ftype == FILE_TYPE_DISK) { + return STD_HANDLE_FILE; + } else if (ftype == FILE_TYPE_PIPE) { + return STD_HANDLE_PIPE; + } else { + DWORD conmode = 0; + BOOL res = GetConsoleMode(h, &conmode); + if (!res && (GetLastError() == ERROR_INVALID_HANDLE)) { + return STD_HANDLE_UNKNOWN; // Unknown character device. + } else { + return STD_HANDLE_CONSOLE; + } + } +} + +OS_Windows::StdHandleType OS_Windows::get_stderr_type() const { + HANDLE h = GetStdHandle(STD_ERROR_HANDLE); + if (h == 0 || h == INVALID_HANDLE_VALUE) { + return STD_HANDLE_INVALID; + } + DWORD ftype = GetFileType(h); + if (ftype == FILE_TYPE_UNKNOWN && GetLastError() != ERROR_SUCCESS) { + return STD_HANDLE_UNKNOWN; + } + ftype &= ~(FILE_TYPE_REMOTE); + + if (ftype == FILE_TYPE_DISK) { + return STD_HANDLE_FILE; + } else if (ftype == FILE_TYPE_PIPE) { + return STD_HANDLE_PIPE; + } else { + DWORD conmode = 0; + BOOL res = GetConsoleMode(h, &conmode); + if (!res && (GetLastError() == ERROR_INVALID_HANDLE)) { + return STD_HANDLE_UNKNOWN; // Unknown character device. + } else { + return STD_HANDLE_CONSOLE; + } + } +} + Error OS_Windows::shell_open(const String &p_uri) { INT_PTR ret = (INT_PTR)ShellExecuteW(nullptr, nullptr, (LPCWSTR)(p_uri.utf16().get_data()), nullptr, nullptr, SW_SHOWNORMAL); if (ret > 32) { @@ -1740,6 +1928,34 @@ String OS_Windows::get_locale() const { return "en"; } +String OS_Windows::get_model_name() const { + HKEY hkey; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Hardware\\Description\\System\\BIOS", 0, KEY_QUERY_VALUE, &hkey) != ERROR_SUCCESS) { + return OS::get_model_name(); + } + + String sys_name; + String board_name; + WCHAR buffer[256]; + DWORD buffer_len = 256; + DWORD vtype = REG_SZ; + if (RegQueryValueExW(hkey, L"SystemProductName", nullptr, &vtype, (LPBYTE)buffer, &buffer_len) == ERROR_SUCCESS && buffer_len != 0) { + sys_name = String::utf16((const char16_t *)buffer, buffer_len).strip_edges(); + } + buffer_len = 256; + if (RegQueryValueExW(hkey, L"BaseBoardProduct", nullptr, &vtype, (LPBYTE)buffer, &buffer_len) == ERROR_SUCCESS && buffer_len != 0) { + board_name = String::utf16((const char16_t *)buffer, buffer_len).strip_edges(); + } + RegCloseKey(hkey); + if (!sys_name.is_empty() && sys_name.to_lower() != "system product name") { + return sys_name; + } + if (!board_name.is_empty() && board_name.to_lower() != "base board product") { + return board_name; + } + return OS::get_model_name(); +} + String OS_Windows::get_processor_name() const { const String id = "Hardware\\Description\\System\\CentralProcessor\\0"; diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 4f9bc049ee..a32e535f0b 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -134,6 +134,8 @@ class OS_Windows : public OS { DWRITE_FONT_WEIGHT _weight_to_dw(int p_weight) const; DWRITE_FONT_STRETCH _stretch_to_dw(int p_stretch) const; + bool is_using_con_wrapper() const; + // functions used by main to initialize/deinitialize the OS protected: virtual void initialize() override; @@ -143,12 +145,17 @@ protected: virtual void finalize() override; virtual void finalize_core() override; - virtual String get_stdin_string() override; + + virtual String get_stdin_string(int64_t p_buffer_size = 1024) override; + virtual PackedByteArray get_stdin_buffer(int64_t p_buffer_size = 1024) override; + virtual StdHandleType get_stdin_type() const override; + virtual StdHandleType get_stdout_type() const override; + virtual StdHandleType get_stderr_type() const override; String _quote_command_line_argument(const String &p_text) const; struct ProcessInfo { - STARTUPINFO si; + STARTUPINFOEX si; PROCESS_INFORMATION pi; mutable bool is_running = true; mutable int exit_code = -1; @@ -210,6 +217,8 @@ public: virtual String get_processor_name() const override; + virtual String get_model_name() const override; + virtual uint64_t get_embedded_pck_offset() const override; virtual String get_config_path() const override; diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp index 6c54faa13a..e25c612008 100644 --- a/platform/windows/windows_terminal_logger.cpp +++ b/platform/windows/windows_terminal_logger.cpp @@ -30,6 +30,8 @@ #include "windows_terminal_logger.h" +#include "core/os/os.h" + #ifdef WINDOWS_ENABLED #include <stdio.h> @@ -78,7 +80,7 @@ void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file } HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); - if (!hCon || hCon == INVALID_HANDLE_VALUE) { + if (OS::get_singleton()->get_stdout_type() != OS::STD_HANDLE_CONSOLE || !hCon || hCon == INVALID_HANDLE_VALUE) { StdLogger::log_error(p_function, p_file, p_line, p_code, p_rationale, p_type); } else { CONSOLE_SCREEN_BUFFER_INFO sbi; //original diff --git a/platform_methods.py b/platform_methods.py index 2c4eb0d1dd..201df3c0b5 100644 --- a/platform_methods.py +++ b/platform_methods.py @@ -8,6 +8,13 @@ import methods # NOTE: The multiprocessing module is not compatible with SCons due to conflict on cPickle +compatibility_platform_aliases = { + "osx": "macos", + "iphone": "ios", + "x11": "linuxbsd", + "javascript": "web", +} + # CPU architecture options. architectures = ["x86_32", "x86_64", "arm32", "arm64", "rv64", "ppc32", "ppc64", "wasm32"] architecture_aliases = { diff --git a/pyproject.toml b/pyproject.toml index a4bfd27816..c4fbe4a459 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ python_version = "3.8" extend-exclude = ["thirdparty"] extend-include = ["SConstruct", "SCsub"] line-length = 120 -target-version = "py37" +target-version = "py38" [tool.ruff.lint] extend-select = [ diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 21648bbc49..0b54d1e604 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -418,7 +418,7 @@ Vector2 PointLight2D::get_texture_offset() const { } PackedStringArray PointLight2D::get_configuration_warnings() const { - PackedStringArray warnings = Node2D::get_configuration_warnings(); + PackedStringArray warnings = Light2D::get_configuration_warnings(); if (!texture.is_valid()) { warnings.push_back(RTR("A texture with the shape of the light must be supplied to the \"Texture\" property.")); diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp index f6502a77e9..c6d1447ad8 100644 --- a/scene/2d/navigation_obstacle_2d.cpp +++ b/scene/2d/navigation_obstacle_2d.cpp @@ -167,8 +167,7 @@ void NavigationObstacle2D::_notification(int p_what) { if (is_debug_enabled) { RS::get_singleton()->canvas_item_clear(debug_canvas_item); - Transform2D debug_transform = Transform2D(0.0, get_global_position()); - RS::get_singleton()->canvas_item_set_transform(debug_canvas_item, debug_transform); + RS::get_singleton()->canvas_item_set_transform(debug_canvas_item, Transform2D()); _update_fake_agent_radius_debug(); _update_static_obstacle_debug(); } @@ -311,6 +310,25 @@ bool NavigationObstacle2D::get_carve_navigation_mesh() const { return carve_navigation_mesh; } +PackedStringArray NavigationObstacle2D::get_configuration_warnings() const { + PackedStringArray warnings = Node2D::get_configuration_warnings(); + + const Vector2 global_scale = get_global_scale(); + if (global_scale.x < 0.001 || global_scale.y < 0.001) { + warnings.push_back(RTR("NavigationObstacle2D does not support negative or zero scaling.")); + } + + if (radius > 0.0 && !get_global_transform().is_conformal()) { + warnings.push_back(RTR("The agent radius can only be scaled uniformly. The largest value along the two axes of the global scale will be used to scale the radius. This value may change in unexpected ways when the node is rotated.")); + } + + if (radius > 0.0 && get_global_skew() != 0.0) { + warnings.push_back(RTR("Skew has no effect on the agent radius.")); + } + + return warnings; +} + void NavigationObstacle2D::_update_map(RID p_map) { map_current = p_map; NavigationServer2D::get_singleton()->obstacle_set_map(obstacle, p_map); @@ -327,8 +345,11 @@ void NavigationObstacle2D::_update_position(const Vector2 p_position) { void NavigationObstacle2D::_update_fake_agent_radius_debug() { if (radius > 0.0 && NavigationServer2D::get_singleton()->get_debug_navigation_avoidance_enable_obstacles_radius()) { Color debug_radius_color = NavigationServer2D::get_singleton()->get_debug_navigation_avoidance_obstacles_radius_color(); - - RS::get_singleton()->canvas_item_add_circle(debug_canvas_item, Vector2(), radius, debug_radius_color); + // Prevent non-positive scaling. + const Vector2 safe_scale = get_global_scale().abs().maxf(0.001); + // Agent radius is a scalar value and does not support non-uniform scaling, choose the largest axis. + const float scaling_max_value = safe_scale[safe_scale.max_axis_index()]; + RS::get_singleton()->canvas_item_add_circle(debug_canvas_item, get_global_position(), scaling_max_value * radius, debug_radius_color); } } #endif // DEBUG_ENABLED @@ -370,7 +391,8 @@ void NavigationObstacle2D::_update_static_obstacle_debug() { debug_obstacle_line_colors.resize(debug_obstacle_line_vertices.size()); debug_obstacle_line_colors.fill(debug_static_obstacle_edge_color); - RS::get_singleton()->canvas_item_add_polyline(debug_canvas_item, debug_obstacle_line_vertices, debug_obstacle_line_colors, 4.0); + // Transforming the vertices directly instead of the canvas item in order to not affect the circle shape by non-uniform scales. + RS::get_singleton()->canvas_item_add_polyline(debug_canvas_item, get_global_transform().xform(debug_obstacle_line_vertices), debug_obstacle_line_colors, 4.0); } } #endif // DEBUG_ENABLED diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h index 28c5f902e6..34e585142d 100644 --- a/scene/2d/navigation_obstacle_2d.h +++ b/scene/2d/navigation_obstacle_2d.h @@ -106,6 +106,8 @@ public: void set_carve_navigation_mesh(bool p_enabled); bool get_carve_navigation_mesh() const; + PackedStringArray get_configuration_warnings() const override; + private: void _update_map(RID p_map); void _update_position(const Vector2 p_position); diff --git a/scene/2d/physics/rigid_body_2d.cpp b/scene/2d/physics/rigid_body_2d.cpp index 402e5c8b95..4b1cde6b7a 100644 --- a/scene/2d/physics/rigid_body_2d.cpp +++ b/scene/2d/physics/rigid_body_2d.cpp @@ -641,7 +641,7 @@ void RigidBody2D::_notification(int p_what) { PackedStringArray RigidBody2D::get_configuration_warnings() const { Transform2D t = get_transform(); - PackedStringArray warnings = CollisionObject2D::get_configuration_warnings(); + PackedStringArray warnings = PhysicsBody2D::get_configuration_warnings(); if (ABS(t.columns[0].length() - 1.0) > 0.05 || ABS(t.columns[1].length() - 1.0) > 0.05) { warnings.push_back(RTR("Size changes to RigidBody2D will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index ddb0635f6b..20cbbc091a 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -75,7 +75,8 @@ void TileMap::_set_tile_map_data_using_compatibility_format(int p_layer, TileMap for (int i = 0; i < c; i += offset) { const uint8_t *ptr = (const uint8_t *)&r[i]; uint8_t local[12]; - for (int j = 0; j < ((p_format >= TileMapDataFormat::TILE_MAP_DATA_FORMAT_2) ? 12 : 8); j++) { + const int buffer_size = (format == TILE_MAP_DATA_FORMAT_2) ? 12 : 8; + for (int j = 0; j < buffer_size; j++) { local[j] = ptr[j]; } diff --git a/scene/2d/tile_map_layer.cpp b/scene/2d/tile_map_layer.cpp index 30bd59c1a2..c4a2f35d31 100644 --- a/scene/2d/tile_map_layer.cpp +++ b/scene/2d/tile_map_layer.cpp @@ -1460,6 +1460,24 @@ void TileMapLayer::_clear_runtime_update_tile_data_for_cell(CellData &r_cell_dat } } +void TileMapLayer::_update_cells_callback(bool p_force_cleanup) { + if (!GDVIRTUAL_IS_OVERRIDDEN(_update_cells)) { + return; + } + + // Check if we should cleanup everything. + bool forced_cleanup = p_force_cleanup || !enabled || tile_set.is_null() || !is_visible_in_tree(); + + // List all the dirty cell's positions to notify script of cell updates. + TypedArray<Vector2i> dirty_cell_positions; + for (SelfList<CellData> *cell_data_list_element = dirty.cell_list.first(); cell_data_list_element; cell_data_list_element = cell_data_list_element->next()) { + CellData &cell_data = *cell_data_list_element->self(); + dirty_cell_positions.push_back(cell_data.coords); + } + + GDVIRTUAL_CALL(_update_cells, dirty_cell_positions, forced_cleanup); +} + TileSet::TerrainsPattern TileMapLayer::_get_best_terrain_pattern_for_constraints(int p_terrain_set, const Vector2i &p_position, const RBSet<TerrainConstraint> &p_constraints, TileSet::TerrainsPattern p_current_pattern) const { if (tile_set.is_null()) { return TileSet::TerrainsPattern(); @@ -1673,6 +1691,10 @@ void TileMapLayer::_internal_update(bool p_force_cleanup) { // This may add cells to the dirty list if a runtime modification has been notified. _build_runtime_update_tile_data(p_force_cleanup); + // Callback for implementing custom subsystems. + // This may add to the dirty list if some cells are changed inside _update_cells. + _update_cells_callback(p_force_cleanup); + // Update all subsystems. _rendering_update(p_force_cleanup); _physics_update(p_force_cleanup); @@ -1861,6 +1883,7 @@ void TileMapLayer::_bind_methods() { GDVIRTUAL_BIND(_use_tile_data_runtime_update, "coords"); GDVIRTUAL_BIND(_tile_data_runtime_update, "coords", "tile_data"); + GDVIRTUAL_BIND(_update_cells, "coords", "forced_cleanup"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "tile_map_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_tile_map_data_from_array", "get_tile_map_data_as_array"); diff --git a/scene/2d/tile_map_layer.h b/scene/2d/tile_map_layer.h index 6cb481849c..912fa2be15 100644 --- a/scene/2d/tile_map_layer.h +++ b/scene/2d/tile_map_layer.h @@ -321,6 +321,7 @@ private: bool _runtime_update_needs_all_cells_cleaned_up = false; void _clear_runtime_update_tile_data(); void _clear_runtime_update_tile_data_for_cell(CellData &r_cell_data); + void _update_cells_callback(bool p_force_cleanup); // Per-system methods. #ifdef DEBUG_ENABLED @@ -462,6 +463,7 @@ public: void notify_runtime_tile_data_update(); GDVIRTUAL1R(bool, _use_tile_data_runtime_update, Vector2i); GDVIRTUAL2(_tile_data_runtime_update, Vector2i, TileData *); + GDVIRTUAL2(_update_cells, TypedArray<Vector2i>, bool); // --- Shortcuts to methods defined in TileSet --- Vector2i map_pattern(const Vector2i &p_position_in_tilemap, const Vector2i &p_coords_in_pattern, Ref<TileMapPattern> p_pattern); diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index b968f39ccb..220608a250 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -430,6 +430,6 @@ void TouchScreenButton::_bind_methods() { } TouchScreenButton::TouchScreenButton() { - unit_rect = Ref<RectangleShape2D>(memnew(RectangleShape2D)); + unit_rect.instantiate(); unit_rect->set_size(Vector2(1, 1)); } diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp index 6b3510a72a..01f15137be 100644 --- a/scene/3d/label_3d.cpp +++ b/scene/3d/label_3d.cpp @@ -318,7 +318,7 @@ Ref<TriangleMesh> Label3D::generate_triangle_mesh() const { facesw[j] = vtx; } - triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); + triangle_mesh.instantiate(); triangle_mesh->create(faces); return triangle_mesh; diff --git a/scene/3d/look_at_modifier_3d.cpp b/scene/3d/look_at_modifier_3d.cpp new file mode 100644 index 0000000000..ad33cd420a --- /dev/null +++ b/scene/3d/look_at_modifier_3d.cpp @@ -0,0 +1,781 @@ +/**************************************************************************/ +/* look_at_modifier_3d.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "look_at_modifier_3d.h" + +void LookAtModifier3D::_validate_property(PropertyInfo &p_property) const { + SkeletonModifier3D::_validate_property(p_property); + + if (p_property.name == "bone" || p_property.name == "origin_bone") { + Skeleton3D *skeleton = get_skeleton(); + if (skeleton) { + p_property.hint = PROPERTY_HINT_ENUM; + p_property.hint_string = skeleton->get_concatenated_bone_names(); + } else { + p_property.hint = PROPERTY_HINT_NONE; + p_property.hint_string = ""; + } + } + + if (origin_from == ORIGIN_FROM_SPECIFIC_BONE) { + if (p_property.name == "origin_external_node") { + p_property.usage = PROPERTY_USAGE_NONE; + } + } else if (origin_from == ORIGIN_FROM_EXTERNAL_NODE) { + if (p_property.name == "origin_bone") { + p_property.usage = PROPERTY_USAGE_NONE; + } + } else { + if (p_property.name == "origin_external_node" || p_property.name == "origin_bone") { + p_property.usage = PROPERTY_USAGE_NONE; + } + } + + if ((!use_angle_limitation && + (p_property.name == "symmetry_limitation" || p_property.name.ends_with("limit_angle") || p_property.name.ends_with("damp_threshold"))) || + (!use_secondary_rotation && p_property.name.begins_with("secondary_")) || + (!symmetry_limitation && (p_property.name == "primary_limit_angle" || p_property.name == "primary_damp_threshold" || p_property.name == "secondary_limit_angle" || p_property.name == "secondary_damp_threshold")) || + (symmetry_limitation && (p_property.name.begins_with("primary_positive") || p_property.name.begins_with("primary_negative") || p_property.name.begins_with("secondary_positive") || (p_property.name.begins_with("secondary_negative"))))) { + p_property.usage = PROPERTY_USAGE_NONE; + } +} + +PackedStringArray LookAtModifier3D::get_configuration_warnings() const { + PackedStringArray warnings = SkeletonModifier3D::get_configuration_warnings(); + if (get_axis_from_bone_axis(forward_axis) == primary_rotation_axis) { + warnings.push_back(RTR("Forward axis and primary rotation axis must not be parallel.")); + } + return warnings; +} + +void LookAtModifier3D::set_bone(int p_bone) { + bone = p_bone; +} + +int LookAtModifier3D::get_bone() const { + return bone; +} + +void LookAtModifier3D::set_forward_axis(BoneAxis p_axis) { + forward_axis = p_axis; + update_configuration_warnings(); +} + +LookAtModifier3D::BoneAxis LookAtModifier3D::get_forward_axis() const { + return forward_axis; +} + +void LookAtModifier3D::set_primary_rotation_axis(Vector3::Axis p_axis) { + primary_rotation_axis = p_axis; + update_configuration_warnings(); +} + +Vector3::Axis LookAtModifier3D::get_primary_rotation_axis() const { + return primary_rotation_axis; +} + +void LookAtModifier3D::set_use_secondary_rotation(bool p_enabled) { + use_secondary_rotation = p_enabled; + notify_property_list_changed(); +} + +bool LookAtModifier3D::is_using_secondary_rotation() const { + return use_secondary_rotation; +} + +void LookAtModifier3D::set_target_node(const NodePath &p_target_node) { + if (target_node != p_target_node) { + init_transition(); + } + target_node = p_target_node; +} + +NodePath LookAtModifier3D::get_target_node() const { + return target_node; +} + +// For origin settings. + +void LookAtModifier3D::set_origin_from(OriginFrom p_origin_from) { + origin_from = p_origin_from; + notify_property_list_changed(); +} + +LookAtModifier3D::OriginFrom LookAtModifier3D::get_origin_from() const { + return origin_from; +} + +void LookAtModifier3D::set_origin_bone(int p_bone) { + origin_bone = p_bone; +} + +int LookAtModifier3D::get_origin_bone() const { + return origin_bone; +} + +void LookAtModifier3D::set_origin_external_node(const NodePath &p_external_node) { + origin_external_node = p_external_node; +} + +NodePath LookAtModifier3D::get_origin_external_node() const { + return origin_external_node; +} + +void LookAtModifier3D::set_origin_offset(const Vector3 &p_offset) { + origin_offset = p_offset; +} + +Vector3 LookAtModifier3D::get_origin_offset() const { + return origin_offset; +} + +void LookAtModifier3D::set_origin_safe_margin(float p_margin) { + origin_safe_margin = p_margin; +} + +float LookAtModifier3D::get_origin_safe_margin() const { + return origin_safe_margin; +} + +// For time-based interpolation. + +void LookAtModifier3D::set_duration(float p_duration) { + duration = p_duration; + if (Math::is_zero_approx(p_duration)) { + time_step = 0; + remaining = 0; + } else { + time_step = 1.0 / p_duration; // Cache to avoid division. + } +} + +float LookAtModifier3D::get_duration() const { + return duration; +} + +void LookAtModifier3D::set_transition_type(Tween::TransitionType p_transition_type) { + transition_type = p_transition_type; +} + +Tween::TransitionType LookAtModifier3D::get_transition_type() const { + return transition_type; +} + +void LookAtModifier3D::set_ease_type(Tween::EaseType p_ease_type) { + ease_type = p_ease_type; +} + +Tween::EaseType LookAtModifier3D::get_ease_type() const { + return ease_type; +} + +// For angle limitation. + +void LookAtModifier3D::set_use_angle_limitation(bool p_enabled) { + use_angle_limitation = p_enabled; + notify_property_list_changed(); +} + +bool LookAtModifier3D::is_using_angle_limitation() const { + return use_angle_limitation; +} + +void LookAtModifier3D::set_symmetry_limitation(bool p_enabled) { + symmetry_limitation = p_enabled; + notify_property_list_changed(); +} + +bool LookAtModifier3D::is_limitation_symmetry() const { + return symmetry_limitation; +} + +void LookAtModifier3D::set_primary_limit_angle(float p_angle) { + primary_limit_angle = p_angle; +} + +float LookAtModifier3D::get_primary_limit_angle() const { + return primary_limit_angle; +} + +void LookAtModifier3D::set_primary_damp_threshold(float p_power) { + primary_damp_threshold = p_power; +} + +float LookAtModifier3D::get_primary_damp_threshold() const { + return primary_damp_threshold; +} + +void LookAtModifier3D::set_primary_positive_limit_angle(float p_angle) { + primary_positive_limit_angle = p_angle; +} + +float LookAtModifier3D::get_primary_positive_limit_angle() const { + return primary_positive_limit_angle; +} + +void LookAtModifier3D::set_primary_positive_damp_threshold(float p_power) { + primary_positive_damp_threshold = p_power; +} + +float LookAtModifier3D::get_primary_positive_damp_threshold() const { + return primary_positive_damp_threshold; +} + +void LookAtModifier3D::set_primary_negative_limit_angle(float p_angle) { + primary_negative_limit_angle = p_angle; +} + +float LookAtModifier3D::get_primary_negative_limit_angle() const { + return primary_negative_limit_angle; +} + +void LookAtModifier3D::set_primary_negative_damp_threshold(float p_power) { + primary_negative_damp_threshold = p_power; +} + +float LookAtModifier3D::get_primary_negative_damp_threshold() const { + return primary_negative_damp_threshold; +} + +void LookAtModifier3D::set_secondary_limit_angle(float p_angle) { + secondary_limit_angle = p_angle; +} + +float LookAtModifier3D::get_secondary_limit_angle() const { + return secondary_limit_angle; +} + +void LookAtModifier3D::set_secondary_damp_threshold(float p_power) { + secondary_damp_threshold = p_power; +} + +float LookAtModifier3D::get_secondary_damp_threshold() const { + return secondary_damp_threshold; +} + +void LookAtModifier3D::set_secondary_positive_limit_angle(float p_angle) { + secondary_positive_limit_angle = p_angle; +} + +float LookAtModifier3D::get_secondary_positive_limit_angle() const { + return secondary_positive_limit_angle; +} + +void LookAtModifier3D::set_secondary_positive_damp_threshold(float p_power) { + secondary_positive_damp_threshold = p_power; +} + +float LookAtModifier3D::get_secondary_positive_damp_threshold() const { + return secondary_positive_damp_threshold; +} + +void LookAtModifier3D::set_secondary_negative_limit_angle(float p_angle) { + secondary_negative_limit_angle = p_angle; +} + +float LookAtModifier3D::get_secondary_negative_limit_angle() const { + return secondary_negative_limit_angle; +} + +void LookAtModifier3D::set_secondary_negative_damp_threshold(float p_power) { + secondary_negative_damp_threshold = p_power; +} + +float LookAtModifier3D::get_secondary_negative_damp_threshold() const { + return secondary_negative_damp_threshold; +} + +bool LookAtModifier3D::is_target_within_limitation() const { + return is_within_limitations; +} + +float LookAtModifier3D::get_interpolation_remaining() const { + return remaining * duration; +} + +bool LookAtModifier3D::is_interpolating() const { + return Math::is_zero_approx(remaining); +} + +// General API. + +void LookAtModifier3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_target_node", "target_node"), &LookAtModifier3D::set_target_node); + ClassDB::bind_method(D_METHOD("get_target_node"), &LookAtModifier3D::get_target_node); + + ClassDB::bind_method(D_METHOD("set_bone", "bone"), &LookAtModifier3D::set_bone); + ClassDB::bind_method(D_METHOD("get_bone"), &LookAtModifier3D::get_bone); + ClassDB::bind_method(D_METHOD("set_forward_axis", "forward_axis"), &LookAtModifier3D::set_forward_axis); + ClassDB::bind_method(D_METHOD("get_forward_axis"), &LookAtModifier3D::get_forward_axis); + ClassDB::bind_method(D_METHOD("set_primary_rotation_axis", "axis"), &LookAtModifier3D::set_primary_rotation_axis); + ClassDB::bind_method(D_METHOD("get_primary_rotation_axis"), &LookAtModifier3D::get_primary_rotation_axis); + ClassDB::bind_method(D_METHOD("set_use_secondary_rotation", "enabled"), &LookAtModifier3D::set_use_secondary_rotation); + ClassDB::bind_method(D_METHOD("is_using_secondary_rotation"), &LookAtModifier3D::is_using_secondary_rotation); + ClassDB::bind_method(D_METHOD("set_origin_safe_margin", "margin"), &LookAtModifier3D::set_origin_safe_margin); + ClassDB::bind_method(D_METHOD("get_origin_safe_margin"), &LookAtModifier3D::get_origin_safe_margin); + + ClassDB::bind_method(D_METHOD("set_origin_from", "origin_from"), &LookAtModifier3D::set_origin_from); + ClassDB::bind_method(D_METHOD("get_origin_from"), &LookAtModifier3D::get_origin_from); + ClassDB::bind_method(D_METHOD("set_origin_bone", "bone"), &LookAtModifier3D::set_origin_bone); + ClassDB::bind_method(D_METHOD("get_origin_bone"), &LookAtModifier3D::get_origin_bone); + ClassDB::bind_method(D_METHOD("set_origin_external_node", "external_node"), &LookAtModifier3D::set_origin_external_node); + ClassDB::bind_method(D_METHOD("get_origin_external_node"), &LookAtModifier3D::get_origin_external_node); + + ClassDB::bind_method(D_METHOD("set_origin_offset", "offset"), &LookAtModifier3D::set_origin_offset); + ClassDB::bind_method(D_METHOD("get_origin_offset"), &LookAtModifier3D::get_origin_offset); + + ClassDB::bind_method(D_METHOD("set_duration", "duration"), &LookAtModifier3D::set_duration); + ClassDB::bind_method(D_METHOD("get_duration"), &LookAtModifier3D::get_duration); + ClassDB::bind_method(D_METHOD("set_transition_type", "transition_type"), &LookAtModifier3D::set_transition_type); + ClassDB::bind_method(D_METHOD("get_transition_type"), &LookAtModifier3D::get_transition_type); + ClassDB::bind_method(D_METHOD("set_ease_type", "ease_type"), &LookAtModifier3D::set_ease_type); + ClassDB::bind_method(D_METHOD("get_ease_type"), &LookAtModifier3D::get_ease_type); + + ClassDB::bind_method(D_METHOD("set_use_angle_limitation", "enabled"), &LookAtModifier3D::set_use_angle_limitation); + ClassDB::bind_method(D_METHOD("is_using_angle_limitation"), &LookAtModifier3D::is_using_angle_limitation); + ClassDB::bind_method(D_METHOD("set_symmetry_limitation", "enabled"), &LookAtModifier3D::set_symmetry_limitation); + ClassDB::bind_method(D_METHOD("is_limitation_symmetry"), &LookAtModifier3D::is_limitation_symmetry); + + ClassDB::bind_method(D_METHOD("set_primary_limit_angle", "angle"), &LookAtModifier3D::set_primary_limit_angle); + ClassDB::bind_method(D_METHOD("get_primary_limit_angle"), &LookAtModifier3D::get_primary_limit_angle); + ClassDB::bind_method(D_METHOD("set_primary_damp_threshold", "power"), &LookAtModifier3D::set_primary_damp_threshold); + ClassDB::bind_method(D_METHOD("get_primary_damp_threshold"), &LookAtModifier3D::get_primary_damp_threshold); + + ClassDB::bind_method(D_METHOD("set_primary_positive_limit_angle", "angle"), &LookAtModifier3D::set_primary_positive_limit_angle); + ClassDB::bind_method(D_METHOD("get_primary_positive_limit_angle"), &LookAtModifier3D::get_primary_positive_limit_angle); + ClassDB::bind_method(D_METHOD("set_primary_positive_damp_threshold", "power"), &LookAtModifier3D::set_primary_positive_damp_threshold); + ClassDB::bind_method(D_METHOD("get_primary_positive_damp_threshold"), &LookAtModifier3D::get_primary_positive_damp_threshold); + ClassDB::bind_method(D_METHOD("set_primary_negative_limit_angle", "angle"), &LookAtModifier3D::set_primary_negative_limit_angle); + ClassDB::bind_method(D_METHOD("get_primary_negative_limit_angle"), &LookAtModifier3D::get_primary_negative_limit_angle); + ClassDB::bind_method(D_METHOD("set_primary_negative_damp_threshold", "power"), &LookAtModifier3D::set_primary_negative_damp_threshold); + ClassDB::bind_method(D_METHOD("get_primary_negative_damp_threshold"), &LookAtModifier3D::get_primary_negative_damp_threshold); + + ClassDB::bind_method(D_METHOD("set_secondary_limit_angle", "angle"), &LookAtModifier3D::set_secondary_limit_angle); + ClassDB::bind_method(D_METHOD("get_secondary_limit_angle"), &LookAtModifier3D::get_secondary_limit_angle); + ClassDB::bind_method(D_METHOD("set_secondary_damp_threshold", "power"), &LookAtModifier3D::set_secondary_damp_threshold); + ClassDB::bind_method(D_METHOD("get_secondary_damp_threshold"), &LookAtModifier3D::get_secondary_damp_threshold); + + ClassDB::bind_method(D_METHOD("set_secondary_positive_limit_angle", "angle"), &LookAtModifier3D::set_secondary_positive_limit_angle); + ClassDB::bind_method(D_METHOD("get_secondary_positive_limit_angle"), &LookAtModifier3D::get_secondary_positive_limit_angle); + ClassDB::bind_method(D_METHOD("set_secondary_positive_damp_threshold", "power"), &LookAtModifier3D::set_secondary_positive_damp_threshold); + ClassDB::bind_method(D_METHOD("get_secondary_positive_damp_threshold"), &LookAtModifier3D::get_secondary_positive_damp_threshold); + ClassDB::bind_method(D_METHOD("set_secondary_negative_limit_angle", "angle"), &LookAtModifier3D::set_secondary_negative_limit_angle); + ClassDB::bind_method(D_METHOD("get_secondary_negative_limit_angle"), &LookAtModifier3D::get_secondary_negative_limit_angle); + ClassDB::bind_method(D_METHOD("set_secondary_negative_damp_threshold", "power"), &LookAtModifier3D::set_secondary_negative_damp_threshold); + ClassDB::bind_method(D_METHOD("get_secondary_negative_damp_threshold"), &LookAtModifier3D::get_secondary_negative_damp_threshold); + + ClassDB::bind_method(D_METHOD("get_interpolation_remaining"), &LookAtModifier3D::get_interpolation_remaining); + ClassDB::bind_method(D_METHOD("is_interpolating"), &LookAtModifier3D::is_interpolating); + ClassDB::bind_method(D_METHOD("is_target_within_limitation"), &LookAtModifier3D::is_target_within_limitation); + + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target_node", PROPERTY_HINT_NODE_TYPE, "Node3D"), "set_target_node", "get_target_node"); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "bone", PROPERTY_HINT_ENUM, ""), "set_bone", "get_bone"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "forward_axis", PROPERTY_HINT_ENUM, "+X,-X,+Y,-Y,+Z,-Z"), "set_forward_axis", "get_forward_axis"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "primary_rotation_axis", PROPERTY_HINT_ENUM, "X,Y,Z"), "set_primary_rotation_axis", "get_primary_rotation_axis"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_secondary_rotation"), "set_use_secondary_rotation", "is_using_secondary_rotation"); + + ADD_GROUP("Origin Settings", "origin_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "origin_from", PROPERTY_HINT_ENUM, "Self,SpecificBone,ExternalNode"), "set_origin_from", "get_origin_from"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "origin_bone", PROPERTY_HINT_ENUM, ""), "set_origin_bone", "get_origin_bone"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "origin_external_node", PROPERTY_HINT_NODE_TYPE, "Node3D"), "set_origin_external_node", "get_origin_external_node"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "origin_offset"), "set_origin_offset", "get_origin_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "origin_safe_margin", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater,suffix:m"), "set_origin_safe_margin", "get_origin_safe_margin"); + + ADD_GROUP("Time Based Interpolation", ""); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "duration", PROPERTY_HINT_RANGE, "0,10,0.001,or_greater,suffix:s"), "set_duration", "get_duration"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "transition_type", PROPERTY_HINT_ENUM, "Linear,Sine,Quint,Quart,Quad,Expo,Elastic,Cubic,Circ,Bounce,Back,Spring"), "set_transition_type", "get_transition_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "ease_type", PROPERTY_HINT_ENUM, "In,Out,InOut,OutIn"), "set_ease_type", "get_ease_type"); + + ADD_GROUP("Angle Limitation", ""); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_angle_limitation"), "set_use_angle_limitation", "is_using_angle_limitation"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "symmetry_limitation"), "set_symmetry_limitation", "is_limitation_symmetry"); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "primary_limit_angle", PROPERTY_HINT_RANGE, "0,360,0.01,radians_as_degrees"), "set_primary_limit_angle", "get_primary_limit_angle"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "primary_damp_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_primary_damp_threshold", "get_primary_damp_threshold"); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "primary_positive_limit_angle", PROPERTY_HINT_RANGE, "0,180,0.01,radians_as_degrees"), "set_primary_positive_limit_angle", "get_primary_positive_limit_angle"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "primary_positive_damp_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_primary_positive_damp_threshold", "get_primary_positive_damp_threshold"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "primary_negative_limit_angle", PROPERTY_HINT_RANGE, "0,180,0.01,radians_as_degrees"), "set_primary_negative_limit_angle", "get_primary_negative_limit_angle"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "primary_negative_damp_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_primary_negative_damp_threshold", "get_primary_negative_damp_threshold"); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "secondary_limit_angle", PROPERTY_HINT_RANGE, "0,360,0.01,radians_as_degrees"), "set_secondary_limit_angle", "get_secondary_limit_angle"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "secondary_damp_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_secondary_damp_threshold", "get_secondary_damp_threshold"); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "secondary_positive_limit_angle", PROPERTY_HINT_RANGE, "0,180,0.01,radians_as_degrees"), "set_secondary_positive_limit_angle", "get_secondary_positive_limit_angle"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "secondary_positive_damp_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_secondary_positive_damp_threshold", "get_secondary_positive_damp_threshold"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "secondary_negative_limit_angle", PROPERTY_HINT_RANGE, "0,180,0.01,radians_as_degrees"), "set_secondary_negative_limit_angle", "get_secondary_negative_limit_angle"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "secondary_negative_damp_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_secondary_negative_damp_threshold", "get_secondary_negative_damp_threshold"); + + BIND_ENUM_CONSTANT(BONE_AXIS_PLUS_X); + BIND_ENUM_CONSTANT(BONE_AXIS_MINUS_X); + BIND_ENUM_CONSTANT(BONE_AXIS_PLUS_Y); + BIND_ENUM_CONSTANT(BONE_AXIS_MINUS_Y); + BIND_ENUM_CONSTANT(BONE_AXIS_PLUS_Z); + BIND_ENUM_CONSTANT(BONE_AXIS_MINUS_Z); + + BIND_ENUM_CONSTANT(ORIGIN_FROM_SELF); + BIND_ENUM_CONSTANT(ORIGIN_FROM_SPECIFIC_BONE); + BIND_ENUM_CONSTANT(ORIGIN_FROM_EXTERNAL_NODE); +} + +void LookAtModifier3D::_process_modification() { + if (!is_inside_tree()) { + return; + } + + Skeleton3D *skeleton = get_skeleton(); + if (!skeleton || bone < 0 || bone >= skeleton->get_bone_count()) { + return; + } + + // Calculate bone rest space in the world. + Transform3D bone_rest_space; + int parent_bone = skeleton->get_bone_parent(bone); + if (parent_bone < 0) { + bone_rest_space = skeleton->get_global_transform() * skeleton->get_bone_rest(bone); + } else { + bone_rest_space = skeleton->get_global_transform() * skeleton->get_bone_global_pose(parent_bone) * skeleton->get_bone_rest(bone); + } + + // Calculate forward_vector and destination. + is_within_limitations = true; + Vector3 prev_forward_vector = forward_vector; + Quaternion destination; + Node3D *target = Object::cast_to<Node3D>(get_node_or_null(target_node)); + if (!target) { + destination = skeleton->get_bone_pose_rotation(bone); + } else { + Transform3D origin_tr; + if (origin_from == ORIGIN_FROM_SPECIFIC_BONE && origin_bone < skeleton->get_bone_count()) { + origin_tr = skeleton->get_global_transform() * skeleton->get_bone_global_pose(origin_bone); + } else if (origin_from == ORIGIN_FROM_EXTERNAL_NODE) { + Node3D *origin_src = Object::cast_to<Node3D>(get_node_or_null(origin_external_node)); + if (origin_src) { + origin_tr = origin_src->get_global_transform(); + } else { + origin_tr = bone_rest_space; + } + } else { + origin_tr = bone_rest_space; + } + forward_vector = bone_rest_space.basis.xform_inv((target->get_global_position() - origin_tr.translated_local(origin_offset).origin)); + forward_vector_nrm = forward_vector.normalized(); + if (forward_vector_nrm.abs().is_equal_approx(get_vector_from_axis(primary_rotation_axis))) { + destination = skeleton->get_bone_pose_rotation(bone); + forward_vector = Vector3(0, 0, 0); // The zero-vector to be used for checking in the line immediately below to avoid animation glitch. + } else { + destination = look_at_with_axes(skeleton->get_bone_rest(bone)).basis.get_rotation_quaternion(); + } + } + + // Detect flipping. + Vector3::Axis current_forward_axis = get_axis_from_bone_axis(forward_axis); + if (is_intersecting_axis(prev_forward_vector, forward_vector, current_forward_axis, secondary_rotation_axis) || + is_intersecting_axis(prev_forward_vector, forward_vector, primary_rotation_axis, primary_rotation_axis, true) || + is_intersecting_axis(prev_forward_vector, forward_vector, secondary_rotation_axis, current_forward_axis) || + (prev_forward_vector != Vector3(0, 0, 0) && forward_vector == Vector3(0, 0, 0)) || + (prev_forward_vector == Vector3(0, 0, 0) && forward_vector != Vector3(0, 0, 0))) { + init_transition(); + } else if (use_angle_limitation && signbit(prev_forward_vector[secondary_rotation_axis]) != signbit(forward_vector[secondary_rotation_axis])) { + // Flipping by angle_limitation can be detected by sign of secondary rotation axes during forward_vector is rotated more than 90 degree from forward_axis (means dot production is negative). + Vector3 prev_forward_vector_nrm = forward_vector.normalized(); + Vector3 rest_forward_vector = get_vector_from_bone_axis(forward_axis); + if (symmetry_limitation) { + if (!Math::is_equal_approx(primary_limit_angle, (float)Math_TAU) && prev_forward_vector_nrm.dot(rest_forward_vector) < 0 && forward_vector_nrm.dot(rest_forward_vector) < 0) { + init_transition(); + } + } else { + if (!Math::is_equal_approx(primary_positive_limit_angle + primary_negative_limit_angle, (float)Math_TAU) && prev_forward_vector_nrm.dot(rest_forward_vector) < 0 && forward_vector_nrm.dot(rest_forward_vector) < 0) { + init_transition(); + } + } + } + + // Do time-based interpolation. + if (remaining > 0) { + double delta = 0.0; + if (skeleton->get_modifier_callback_mode_process() == Skeleton3D::MODIFIER_CALLBACK_MODE_PROCESS_IDLE) { + delta = get_process_delta_time(); + } else { + delta = get_physics_process_delta_time(); + } + remaining = MAX(0, remaining - time_step * delta); + if (use_angle_limitation) { + // Interpolate through the rest same as AnimationTree blending for preventing to penetrate the bone into the body. + Quaternion rest = skeleton->get_bone_rest(bone).basis.get_rotation_quaternion(); + float weight = Tween::run_equation(transition_type, ease_type, 1 - remaining, 0.0, 1.0, 1.0); + destination = rest * Quaternion().slerp(rest.inverse() * from_q, 1 - weight) * Quaternion().slerp(rest.inverse() * destination, weight); + } else { + destination = from_q.slerp(destination, Tween::run_equation(transition_type, ease_type, 1 - remaining, 0.0, 1.0, 1.0)); + } + } + + skeleton->set_bone_pose_rotation(bone, destination); + prev_q = destination; +} + +bool LookAtModifier3D::is_intersecting_axis(const Vector3 &p_prev, const Vector3 &p_current, Vector3::Axis p_flipping_axis, Vector3::Axis p_check_axis, bool p_check_plane) const { + // Prevent that the angular velocity does not become too large. + // Check that is p_flipping_axis flipped nearby p_check_axis (close than origin_safe_margin) or not. If p_check_plane is true, check two axes of crossed plane. + if (p_check_plane) { + if (get_projection_vector(p_prev, p_check_axis).length() > origin_safe_margin && get_projection_vector(p_current, p_check_axis).length() > origin_safe_margin) { + return false; + } + } else if (Math::abs(p_prev[p_check_axis]) > origin_safe_margin && Math::abs(p_current[p_check_axis]) > origin_safe_margin) { + return false; + } + + return signbit(p_prev[p_flipping_axis]) != signbit(p_current[p_flipping_axis]); +} + +Vector3 LookAtModifier3D::get_basis_vector_from_bone_axis(const Basis &p_basis, LookAtModifier3D::BoneAxis p_axis) const { + Vector3 ret; + switch (p_axis) { + case BONE_AXIS_PLUS_X: { + ret = p_basis.get_column(0); + } break; + case BONE_AXIS_MINUS_X: { + ret = -p_basis.get_column(0); + } break; + case BONE_AXIS_PLUS_Y: { + ret = p_basis.get_column(1); + } break; + case BONE_AXIS_MINUS_Y: { + ret = -p_basis.get_column(1); + } break; + case BONE_AXIS_PLUS_Z: { + ret = p_basis.get_column(2); + } break; + case BONE_AXIS_MINUS_Z: { + ret = -p_basis.get_column(2); + } break; + } + return ret; +} + +Vector3 LookAtModifier3D::get_vector_from_bone_axis(const LookAtModifier3D::BoneAxis &p_axis) const { + Vector3 ret; + switch (p_axis) { + case BONE_AXIS_PLUS_X: { + ret = Vector3(1, 0, 0); + } break; + case BONE_AXIS_MINUS_X: { + ret = Vector3(-1, 0, 0); + } break; + case BONE_AXIS_PLUS_Y: { + ret = Vector3(0, 1, 0); + } break; + case BONE_AXIS_MINUS_Y: { + ret = Vector3(0, -1, 0); + } break; + case BONE_AXIS_PLUS_Z: { + ret = Vector3(0, 0, 1); + } break; + case BONE_AXIS_MINUS_Z: { + ret = Vector3(0, 0, -1); + } break; + } + return ret; +} + +Vector3 LookAtModifier3D::get_vector_from_axis(const Vector3::Axis &p_axis) const { + Vector3 ret; + switch (p_axis) { + case Vector3::AXIS_X: { + ret = Vector3(1, 0, 0); + } break; + case Vector3::AXIS_Y: { + ret = Vector3(0, 1, 0); + } break; + case Vector3::AXIS_Z: { + ret = Vector3(0, 0, 1); + } break; + } + return ret; +} + +Vector3::Axis LookAtModifier3D::get_axis_from_bone_axis(BoneAxis p_axis) const { + Vector3::Axis ret = Vector3::AXIS_X; + switch (p_axis) { + case BONE_AXIS_PLUS_X: + case BONE_AXIS_MINUS_X: { + ret = Vector3::AXIS_X; + } break; + case BONE_AXIS_PLUS_Y: + case BONE_AXIS_MINUS_Y: { + ret = Vector3::AXIS_Y; + } break; + case BONE_AXIS_PLUS_Z: + case BONE_AXIS_MINUS_Z: { + ret = Vector3::AXIS_Z; + } break; + } + return ret; +} + +Vector2 LookAtModifier3D::get_projection_vector(const Vector3 &p_vector, Vector3::Axis p_axis) const { + // NOTE: axis is swapped between 2D and 3D. + Vector2 ret; + switch (p_axis) { + case Vector3::AXIS_X: { + ret = Vector2(p_vector.z, p_vector.y); + } break; + case Vector3::AXIS_Y: { + ret = Vector2(p_vector.x, p_vector.z); + } break; + case Vector3::AXIS_Z: { + ret = Vector2(p_vector.y, p_vector.x); + } break; + } + return ret; +} + +float LookAtModifier3D::remap_damped(float p_from, float p_to, float p_damp_threshold, float p_value) const { + float sign = signbit(p_value) ? -1.0f : 1.0f; + float abs_value = Math::abs(p_value); + + if (Math::is_equal_approx(p_damp_threshold, 1.0f) || Math::is_zero_approx(p_to)) { + return sign * CLAMP(abs_value, p_from, p_to); // Avoid division by zero. + } + + float value = Math::inverse_lerp(p_from, p_to, abs_value); + + if (value <= p_damp_threshold) { + return sign * CLAMP(abs_value, p_from, p_to); + } + + double limit = Math_PI; + double inv_to = 1.0 / p_to; + double end_x = limit * inv_to; + double position = abs_value * inv_to; + Vector2 start = Vector2(p_damp_threshold, p_damp_threshold); + Vector2 mid = Vector2(1.0, 1.0); + Vector2 end = Vector2(end_x, 1.0); + value = get_bspline_y(start, mid, end, position); + + return sign * Math::lerp(p_from, p_to, value); +} + +double LookAtModifier3D::get_bspline_y(const Vector2 &p_from, const Vector2 &p_control, const Vector2 &p_to, double p_x) const { + double a = p_from.x - 2.0 * p_control.x + p_to.x; + double b = -2.0 * p_from.x + 2.0 * p_control.x; + double c = p_from.x - p_x; + double t = 0.0; + if (Math::is_zero_approx(a)) { + t = -c / b; // Almost linear. + } else { + double discriminant = b * b - 4.0 * a * c; + double sqrt_discriminant = Math::sqrt(discriminant); + double e = 1.0 / (2.0 * a); + double t1 = (-b + sqrt_discriminant) * e; + t = (0.0 <= t1 && t1 <= 1.0) ? t1 : (-b - sqrt_discriminant) * e; + } + double u = 1.0 - t; + double y = u * u * p_from.y + 2.0 * u * t * p_control.y + t * t * p_to.y; + return y; +} + +Transform3D LookAtModifier3D::look_at_with_axes(const Transform3D &p_rest) { + // Primary rotation by projection to 2D plane by xform_inv and picking elements. + Vector3 current_vector = get_basis_vector_from_bone_axis(p_rest.basis, forward_axis).normalized(); + Vector2 src_vec2 = get_projection_vector(p_rest.basis.xform_inv(forward_vector_nrm), primary_rotation_axis).normalized(); + Vector2 dst_vec2 = get_projection_vector(p_rest.basis.xform_inv(current_vector), primary_rotation_axis).normalized(); + real_t calculated_angle = src_vec2.angle_to(dst_vec2); + Transform3D primary_result = p_rest.rotated_local(get_vector_from_axis(primary_rotation_axis), calculated_angle); + Transform3D current_result = primary_result; // primary_result will be used by calculation of secondary rotation, current_result is rotated by that. + float limit_angle = 0.0; + float damp_threshold = 0.0; + + if (use_angle_limitation) { + if (symmetry_limitation) { + limit_angle = primary_limit_angle * 0.5f; + damp_threshold = primary_damp_threshold; + } else { + if (signbit(calculated_angle)) { + limit_angle = primary_negative_limit_angle; + damp_threshold = primary_negative_damp_threshold; + } else { + limit_angle = primary_positive_limit_angle; + damp_threshold = primary_positive_damp_threshold; + } + } + if (Math::abs(calculated_angle) > limit_angle) { + is_within_limitations = false; + } + calculated_angle = remap_damped(0, limit_angle, damp_threshold, calculated_angle); + current_result = p_rest.rotated_local(get_vector_from_axis(primary_rotation_axis), calculated_angle); + } + + // Needs for detecting flipping even if use_secondary_rotation is false. + Vector3 secondary_plane = get_vector_from_bone_axis(forward_axis) + get_vector_from_axis(primary_rotation_axis); + secondary_rotation_axis = Math::is_zero_approx(secondary_plane.x) ? Vector3::AXIS_X : (Math::is_zero_approx(secondary_plane.y) ? Vector3::AXIS_Y : Vector3::AXIS_Z); + + if (!use_secondary_rotation) { + return current_result; + } + + // Secondary rotation by projection to 2D plane by xform_inv and picking elements. + current_vector = get_basis_vector_from_bone_axis(primary_result.basis, forward_axis).normalized(); + src_vec2 = get_projection_vector(primary_result.basis.xform_inv(forward_vector_nrm), secondary_rotation_axis).normalized(); + dst_vec2 = get_projection_vector(primary_result.basis.xform_inv(current_vector), secondary_rotation_axis).normalized(); + calculated_angle = src_vec2.angle_to(dst_vec2); + + if (use_angle_limitation) { + if (symmetry_limitation) { + limit_angle = secondary_limit_angle * 0.5f; + damp_threshold = secondary_damp_threshold; + } else { + if (signbit(calculated_angle)) { + limit_angle = secondary_negative_limit_angle; + damp_threshold = secondary_negative_damp_threshold; + } else { + limit_angle = secondary_positive_limit_angle; + damp_threshold = secondary_positive_damp_threshold; + } + } + if (Math::abs(calculated_angle) > limit_angle) { + is_within_limitations = false; + } + calculated_angle = remap_damped(0, limit_angle, damp_threshold, calculated_angle); + } + + current_result = current_result.rotated_local(get_vector_from_axis(secondary_rotation_axis), calculated_angle); + + return current_result; +} + +void LookAtModifier3D::init_transition() { + if (Math::is_zero_approx(duration)) { + return; + } + from_q = prev_q; + remaining = 1.0; +} diff --git a/scene/3d/look_at_modifier_3d.h b/scene/3d/look_at_modifier_3d.h new file mode 100644 index 0000000000..5f3c4e8b1c --- /dev/null +++ b/scene/3d/look_at_modifier_3d.h @@ -0,0 +1,199 @@ +/**************************************************************************/ +/* look_at_modifier_3d.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef LOOK_AT_MODIFIER_3D_H +#define LOOK_AT_MODIFIER_3D_H + +#include "scene/3d/skeleton_modifier_3d.h" +#include "scene/animation/tween.h" + +class LookAtModifier3D : public SkeletonModifier3D { + GDCLASS(LookAtModifier3D, SkeletonModifier3D); + +public: + enum BoneAxis { + BONE_AXIS_PLUS_X, + BONE_AXIS_MINUS_X, + BONE_AXIS_PLUS_Y, + BONE_AXIS_MINUS_Y, + BONE_AXIS_PLUS_Z, + BONE_AXIS_MINUS_Z, + }; + + enum OriginFrom { + ORIGIN_FROM_SELF, + ORIGIN_FROM_SPECIFIC_BONE, + ORIGIN_FROM_EXTERNAL_NODE, + }; + +private: + int bone = 0; + + Vector3 forward_vector; + Vector3 forward_vector_nrm; + BoneAxis forward_axis = BONE_AXIS_PLUS_Z; + Vector3::Axis primary_rotation_axis = Vector3::AXIS_Y; + Vector3::Axis secondary_rotation_axis = Vector3::AXIS_X; + bool use_secondary_rotation = true; + + OriginFrom origin_from = ORIGIN_FROM_SELF; + int origin_bone = -1; + NodePath origin_external_node; + + Vector3 origin_offset; + float origin_safe_margin = 0.1; + + NodePath target_node; + + float duration = 0; + Tween::TransitionType transition_type = Tween::TRANS_LINEAR; + Tween::EaseType ease_type = Tween::EASE_IN; + + bool use_angle_limitation = false; + bool symmetry_limitation = true; + + float primary_limit_angle = Math_TAU; + float primary_damp_threshold = 1.0f; + float primary_positive_limit_angle = Math_PI; + float primary_positive_damp_threshold = 1.0f; + float primary_negative_limit_angle = Math_PI; + float primary_negative_damp_threshold = 1.0f; + + float secondary_limit_angle = Math_TAU; + float secondary_damp_threshold = 1.0f; + float secondary_positive_limit_angle = Math_PI; + float secondary_positive_damp_threshold = 1.0f; + float secondary_negative_limit_angle = Math_PI; + float secondary_negative_damp_threshold = 1.0f; + + bool is_within_limitations = false; + + // For time-based interpolation. + Quaternion from_q; + Quaternion prev_q; + + float remaining = 0; + float time_step = 1.0; + + Vector3 get_basis_vector_from_bone_axis(const Basis &p_basis, BoneAxis p_axis) const; + Vector3 get_vector_from_bone_axis(const BoneAxis &p_axis) const; + Vector3 get_vector_from_axis(const Vector3::Axis &p_axis) const; + Vector3::Axis get_axis_from_bone_axis(BoneAxis p_axis) const; + Vector2 get_projection_vector(const Vector3 &p_vector, Vector3::Axis p_axis) const; + float remap_damped(float p_from, float p_to, float p_damp_threshold, float p_value) const; + double get_bspline_y(const Vector2 &p_from, const Vector2 &p_control, const Vector2 &p_to, double p_x) const; + bool is_intersecting_axis(const Vector3 &p_prev, const Vector3 &p_current, Vector3::Axis p_flipping_axis, Vector3::Axis p_check_axis, bool p_check_plane = false) const; + + Transform3D look_at_with_axes(const Transform3D &p_rest); + void init_transition(); + +protected: + virtual PackedStringArray get_configuration_warnings() const override; + void _validate_property(PropertyInfo &p_property) const; + + static void _bind_methods(); + + virtual void _process_modification() override; + +public: + void set_bone(int p_bone); + int get_bone() const; + + void set_forward_axis(BoneAxis p_axis); + BoneAxis get_forward_axis() const; + void set_primary_rotation_axis(Vector3::Axis p_axis); + Vector3::Axis get_primary_rotation_axis() const; + void set_use_secondary_rotation(bool p_enabled); + bool is_using_secondary_rotation() const; + + void set_origin_from(OriginFrom p_origin_from); + OriginFrom get_origin_from() const; + void set_origin_bone(int p_bone); + int get_origin_bone() const; + void set_origin_external_node(const NodePath &p_external_node); + NodePath get_origin_external_node() const; + + void set_origin_offset(const Vector3 &p_offset); + Vector3 get_origin_offset() const; + void set_origin_safe_margin(float p_margin); + float get_origin_safe_margin() const; + + void set_target_node(const NodePath &p_target_node); + NodePath get_target_node() const; + + void set_duration(float p_duration); + float get_duration() const; + void set_transition_type(Tween::TransitionType p_transition_type); + Tween::TransitionType get_transition_type() const; + void set_ease_type(Tween::EaseType p_ease_type); + Tween::EaseType get_ease_type() const; + + void set_use_angle_limitation(bool p_enabled); + bool is_using_angle_limitation() const; + void set_symmetry_limitation(bool p_enabled); + bool is_limitation_symmetry() const; + + void set_primary_limit_angle(float p_angle); + float get_primary_limit_angle() const; + void set_primary_damp_threshold(float p_power); + float get_primary_damp_threshold() const; + + void set_primary_positive_limit_angle(float p_angle); + float get_primary_positive_limit_angle() const; + void set_primary_positive_damp_threshold(float p_power); + float get_primary_positive_damp_threshold() const; + void set_primary_negative_limit_angle(float p_angle); + float get_primary_negative_limit_angle() const; + void set_primary_negative_damp_threshold(float p_power); + float get_primary_negative_damp_threshold() const; + + void set_secondary_limit_angle(float p_angle); + float get_secondary_limit_angle() const; + void set_secondary_damp_threshold(float p_power); + float get_secondary_damp_threshold() const; + + void set_secondary_positive_limit_angle(float p_angle); + float get_secondary_positive_limit_angle() const; + void set_secondary_positive_damp_threshold(float p_power); + float get_secondary_positive_damp_threshold() const; + void set_secondary_negative_limit_angle(float p_angle); + float get_secondary_negative_limit_angle() const; + void set_secondary_negative_damp_threshold(float p_power); + float get_secondary_negative_damp_threshold() const; + + float get_interpolation_remaining() const; + bool is_interpolating() const; + bool is_target_within_limitation() const; +}; + +VARIANT_ENUM_CAST(LookAtModifier3D::BoneAxis); +VARIANT_ENUM_CAST(LookAtModifier3D::OriginFrom); + +#endif // LOOK_AT_MODIFIER_3D_H diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index 9242c2a2ea..faf138896a 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -1081,8 +1081,8 @@ void NavigationAgent3D::_update_debug_path() { debug_path_instance = RenderingServer::get_singleton()->instance_create(); } - if (!debug_path_mesh.is_valid()) { - debug_path_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + if (debug_path_mesh.is_null()) { + debug_path_mesh.instantiate(); } debug_path_mesh->clear_surfaces(); diff --git a/scene/3d/navigation_link_3d.cpp b/scene/3d/navigation_link_3d.cpp index 0cce21b9d0..9e29384fc9 100644 --- a/scene/3d/navigation_link_3d.cpp +++ b/scene/3d/navigation_link_3d.cpp @@ -56,8 +56,8 @@ void NavigationLink3D::_update_debug_mesh() { debug_instance = RenderingServer::get_singleton()->instance_create(); } - if (!debug_mesh.is_valid()) { - debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + if (debug_mesh.is_null()) { + debug_mesh.instantiate(); } RID nav_map = get_world_3d()->get_navigation_map(); diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp index 2eb04a0054..68a6505897 100644 --- a/scene/3d/navigation_obstacle_3d.cpp +++ b/scene/3d/navigation_obstacle_3d.cpp @@ -92,30 +92,26 @@ void NavigationObstacle3D::_notification(int p_what) { } else { _update_map(RID()); } - previous_transform = get_global_transform(); // need to trigger map controlled agent assignment somehow for the fake_agent since obstacles use no callback like regular agents NavigationServer3D::get_singleton()->obstacle_set_avoidance_enabled(obstacle, avoidance_enabled); - _update_position(get_global_transform().origin); + _update_position(get_global_position()); set_physics_process_internal(true); #ifdef DEBUG_ENABLED - if ((NavigationServer3D::get_singleton()->get_debug_avoidance_enabled()) && - (NavigationServer3D::get_singleton()->get_debug_navigation_avoidance_enable_obstacles_radius())) { - _update_fake_agent_radius_debug(); - _update_static_obstacle_debug(); - } + _update_debug(); #endif // DEBUG_ENABLED } break; +#ifdef TOOLS_ENABLED + case NOTIFICATION_TRANSFORM_CHANGED: { + update_gizmos(); + } break; +#endif // TOOLS_ENABLED + case NOTIFICATION_EXIT_TREE: { set_physics_process_internal(false); _update_map(RID()); #ifdef DEBUG_ENABLED - if (fake_agent_radius_debug_instance.is_valid()) { - RS::get_singleton()->instance_set_visible(fake_agent_radius_debug_instance, false); - } - if (static_obstacle_debug_instance.is_valid()) { - RS::get_singleton()->instance_set_visible(static_obstacle_debug_instance, false); - } + _update_debug(); #endif // DEBUG_ENABLED } break; @@ -151,20 +147,13 @@ void NavigationObstacle3D::_notification(int p_what) { #ifdef DEBUG_ENABLED case NOTIFICATION_VISIBILITY_CHANGED: { - if (is_inside_tree()) { - if (fake_agent_radius_debug_instance.is_valid()) { - RS::get_singleton()->instance_set_visible(fake_agent_radius_debug_instance, is_visible_in_tree()); - } - if (static_obstacle_debug_instance.is_valid()) { - RS::get_singleton()->instance_set_visible(static_obstacle_debug_instance, is_visible_in_tree()); - } - } + _update_debug(); } break; #endif // DEBUG_ENABLED case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { if (is_inside_tree()) { - _update_position(get_global_transform().origin); + _update_position(get_global_position()); if (velocity_submitted) { velocity_submitted = false; @@ -175,15 +164,23 @@ void NavigationObstacle3D::_notification(int p_what) { previous_velocity = velocity; } #ifdef DEBUG_ENABLED - if (fake_agent_radius_debug_instance.is_valid() && radius > 0.0) { - Transform3D debug_transform; - debug_transform.origin = get_global_position(); - RS::get_singleton()->instance_set_transform(fake_agent_radius_debug_instance, debug_transform); + if (fake_agent_radius_debug_instance_rid.is_valid() && radius > 0.0) { + // Prevent non-positive scaling. + const Vector3 safe_scale = get_global_basis().get_scale().abs().maxf(0.001); + // Agent radius is a scalar value and does not support non-uniform scaling, choose the largest axis. + const float scaling_max_value = safe_scale[safe_scale.max_axis_index()]; + const Vector3 uniform_max_scale = Vector3(scaling_max_value, scaling_max_value, scaling_max_value); + const Transform3D debug_transform = Transform3D(Basis().scaled(uniform_max_scale), get_global_position()); + + RS::get_singleton()->instance_set_transform(fake_agent_radius_debug_instance_rid, debug_transform); } - if (static_obstacle_debug_instance.is_valid() && get_vertices().size() > 0) { - Transform3D debug_transform; - debug_transform.origin = get_global_position(); - RS::get_singleton()->instance_set_transform(static_obstacle_debug_instance, debug_transform); + if (static_obstacle_debug_instance_rid.is_valid() && get_vertices().size() > 0) { + // Prevent non-positive scaling. + const Vector3 safe_scale = get_global_basis().get_scale().abs().maxf(0.001); + // Obstacles are projected to the xz-plane, so only rotation around the y-axis can be taken into account. + const Transform3D debug_transform = Transform3D(Basis().scaled(safe_scale).rotated(Vector3(0.0, 1.0, 0.0), get_global_rotation().y), get_global_position()); + + RS::get_singleton()->instance_set_transform(static_obstacle_debug_instance_rid, debug_transform); } #endif // DEBUG_ENABLED } @@ -192,53 +189,79 @@ void NavigationObstacle3D::_notification(int p_what) { } NavigationObstacle3D::NavigationObstacle3D() { - obstacle = NavigationServer3D::get_singleton()->obstacle_create(); + NavigationServer3D *ns3d = NavigationServer3D::get_singleton(); - NavigationServer3D::get_singleton()->obstacle_set_height(obstacle, height); - NavigationServer3D::get_singleton()->obstacle_set_radius(obstacle, radius); - NavigationServer3D::get_singleton()->obstacle_set_vertices(obstacle, vertices); - NavigationServer3D::get_singleton()->obstacle_set_avoidance_layers(obstacle, avoidance_layers); - NavigationServer3D::get_singleton()->obstacle_set_use_3d_avoidance(obstacle, use_3d_avoidance); - NavigationServer3D::get_singleton()->obstacle_set_avoidance_enabled(obstacle, avoidance_enabled); + obstacle = ns3d->obstacle_create(); + + ns3d->obstacle_set_height(obstacle, height); + ns3d->obstacle_set_radius(obstacle, radius); + ns3d->obstacle_set_vertices(obstacle, vertices); + ns3d->obstacle_set_avoidance_layers(obstacle, avoidance_layers); + ns3d->obstacle_set_use_3d_avoidance(obstacle, use_3d_avoidance); + ns3d->obstacle_set_avoidance_enabled(obstacle, avoidance_enabled); #ifdef DEBUG_ENABLED - NavigationServer3D::get_singleton()->connect("avoidance_debug_changed", callable_mp(this, &NavigationObstacle3D::_update_fake_agent_radius_debug)); - NavigationServer3D::get_singleton()->connect("avoidance_debug_changed", callable_mp(this, &NavigationObstacle3D::_update_static_obstacle_debug)); + RenderingServer *rs = RenderingServer::get_singleton(); + + fake_agent_radius_debug_mesh_rid = rs->mesh_create(); + static_obstacle_debug_mesh_rid = rs->mesh_create(); + + fake_agent_radius_debug_instance_rid = rs->instance_create(); + static_obstacle_debug_instance_rid = rs->instance_create(); + + rs->instance_set_base(fake_agent_radius_debug_instance_rid, fake_agent_radius_debug_mesh_rid); + rs->instance_set_base(static_obstacle_debug_instance_rid, static_obstacle_debug_mesh_rid); + + ns3d->connect("avoidance_debug_changed", callable_mp(this, &NavigationObstacle3D::_update_fake_agent_radius_debug)); + ns3d->connect("avoidance_debug_changed", callable_mp(this, &NavigationObstacle3D::_update_static_obstacle_debug)); _update_fake_agent_radius_debug(); _update_static_obstacle_debug(); #endif // DEBUG_ENABLED + +#ifdef TOOLS_ENABLED + set_notify_transform(true); +#endif // TOOLS_ENABLED } NavigationObstacle3D::~NavigationObstacle3D() { - ERR_FAIL_NULL(NavigationServer3D::get_singleton()); + NavigationServer3D *ns3d = NavigationServer3D::get_singleton(); + ERR_FAIL_NULL(ns3d); - NavigationServer3D::get_singleton()->free(obstacle); + ns3d->free(obstacle); obstacle = RID(); #ifdef DEBUG_ENABLED - NavigationServer3D::get_singleton()->disconnect("avoidance_debug_changed", callable_mp(this, &NavigationObstacle3D::_update_fake_agent_radius_debug)); - NavigationServer3D::get_singleton()->disconnect("avoidance_debug_changed", callable_mp(this, &NavigationObstacle3D::_update_static_obstacle_debug)); - if (fake_agent_radius_debug_instance.is_valid()) { - RenderingServer::get_singleton()->free(fake_agent_radius_debug_instance); + ns3d->disconnect("avoidance_debug_changed", callable_mp(this, &NavigationObstacle3D::_update_fake_agent_radius_debug)); + ns3d->disconnect("avoidance_debug_changed", callable_mp(this, &NavigationObstacle3D::_update_static_obstacle_debug)); + + RenderingServer *rs = RenderingServer::get_singleton(); + ERR_FAIL_NULL(rs); + if (fake_agent_radius_debug_instance_rid.is_valid()) { + rs->free(fake_agent_radius_debug_instance_rid); + fake_agent_radius_debug_instance_rid = RID(); } - if (fake_agent_radius_debug_mesh.is_valid()) { - RenderingServer::get_singleton()->free(fake_agent_radius_debug_mesh->get_rid()); + if (fake_agent_radius_debug_mesh_rid.is_valid()) { + rs->free(fake_agent_radius_debug_mesh_rid); + fake_agent_radius_debug_mesh_rid = RID(); } - - if (static_obstacle_debug_instance.is_valid()) { - RenderingServer::get_singleton()->free(static_obstacle_debug_instance); + if (static_obstacle_debug_instance_rid.is_valid()) { + rs->free(static_obstacle_debug_instance_rid); + static_obstacle_debug_instance_rid = RID(); } - if (static_obstacle_debug_mesh.is_valid()) { - RenderingServer::get_singleton()->free(static_obstacle_debug_mesh->get_rid()); + if (static_obstacle_debug_mesh_rid.is_valid()) { + rs->free(static_obstacle_debug_mesh_rid); + static_obstacle_debug_mesh_rid = RID(); } #endif // DEBUG_ENABLED } void NavigationObstacle3D::set_vertices(const Vector<Vector3> &p_vertices) { vertices = p_vertices; + NavigationServer3D::get_singleton()->obstacle_set_vertices(obstacle, vertices); #ifdef DEBUG_ENABLED _update_static_obstacle_debug(); + update_gizmos(); #endif // DEBUG_ENABLED } @@ -270,6 +293,7 @@ void NavigationObstacle3D::set_radius(real_t p_radius) { #ifdef DEBUG_ENABLED _update_fake_agent_radius_debug(); + update_gizmos(); #endif // DEBUG_ENABLED } @@ -284,6 +308,7 @@ void NavigationObstacle3D::set_height(real_t p_height) { #ifdef DEBUG_ENABLED _update_static_obstacle_debug(); + update_gizmos(); #endif // DEBUG_ENABLED } @@ -354,6 +379,25 @@ bool NavigationObstacle3D::get_carve_navigation_mesh() const { return carve_navigation_mesh; } +PackedStringArray NavigationObstacle3D::get_configuration_warnings() const { + PackedStringArray warnings = Node3D::get_configuration_warnings(); + + if (get_global_rotation().x != 0.0 || get_global_rotation().z != 0.0) { + warnings.push_back(RTR("NavigationObstacle3D only takes global rotation around the y-axis into account. Rotations around the x-axis or z-axis might lead to unexpected results.")); + } + + const Vector3 global_scale = get_global_basis().get_scale(); + if (global_scale.x < 0.001 || global_scale.y < 0.001 || global_scale.z < 0.001) { + warnings.push_back(RTR("NavigationObstacle3D does not support negative or zero scaling.")); + } + + if (radius > 0.0 && !get_global_basis().is_conformal()) { + warnings.push_back(RTR("The agent radius can only be scaled uniformly. The largest scale value along the three axes will be used.")); + } + + return warnings; +} + void NavigationObstacle3D::_update_map(RID p_map) { NavigationServer3D::get_singleton()->obstacle_set_map(obstacle, p_map); map_current = p_map; @@ -369,30 +413,43 @@ void NavigationObstacle3D::_update_use_3d_avoidance(bool p_use_3d_avoidance) { } #ifdef DEBUG_ENABLED +void NavigationObstacle3D::_update_debug() { + RenderingServer *rs = RenderingServer::get_singleton(); + if (is_inside_tree()) { + rs->instance_set_visible(fake_agent_radius_debug_instance_rid, is_visible_in_tree()); + rs->instance_set_visible(static_obstacle_debug_instance_rid, is_visible_in_tree()); + rs->instance_set_scenario(fake_agent_radius_debug_instance_rid, get_world_3d()->get_scenario()); + rs->instance_set_scenario(static_obstacle_debug_instance_rid, get_world_3d()->get_scenario()); + rs->instance_set_transform(fake_agent_radius_debug_instance_rid, Transform3D(Basis(), get_global_position())); + rs->instance_set_transform(static_obstacle_debug_instance_rid, Transform3D(Basis(), get_global_position())); + _update_fake_agent_radius_debug(); + _update_static_obstacle_debug(); + } else { + rs->mesh_clear(fake_agent_radius_debug_mesh_rid); + rs->mesh_clear(static_obstacle_debug_mesh_rid); + rs->instance_set_scenario(fake_agent_radius_debug_instance_rid, RID()); + rs->instance_set_scenario(static_obstacle_debug_instance_rid, RID()); + } +} + void NavigationObstacle3D::_update_fake_agent_radius_debug() { + NavigationServer3D *ns3d = NavigationServer3D::get_singleton(); + RenderingServer *rs = RenderingServer::get_singleton(); + bool is_debug_enabled = false; if (Engine::get_singleton()->is_editor_hint()) { is_debug_enabled = true; - } else if (NavigationServer3D::get_singleton()->get_debug_enabled() && - NavigationServer3D::get_singleton()->get_debug_avoidance_enabled() && - NavigationServer3D::get_singleton()->get_debug_navigation_avoidance_enable_obstacles_radius()) { + } else if (ns3d->get_debug_enabled() && + ns3d->get_debug_avoidance_enabled() && + ns3d->get_debug_navigation_avoidance_enable_obstacles_radius()) { is_debug_enabled = true; } - if (is_debug_enabled == false) { - if (fake_agent_radius_debug_instance.is_valid()) { - RS::get_singleton()->instance_set_visible(fake_agent_radius_debug_instance, false); - } - return; - } + rs->mesh_clear(fake_agent_radius_debug_mesh_rid); - if (!fake_agent_radius_debug_instance.is_valid()) { - fake_agent_radius_debug_instance = RenderingServer::get_singleton()->instance_create(); - } - if (!fake_agent_radius_debug_mesh.is_valid()) { - fake_agent_radius_debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + if (!is_debug_enabled) { + return; } - fake_agent_radius_debug_mesh->clear_surfaces(); Vector<Vector3> face_vertex_array; Vector<int> face_indices_array; @@ -447,147 +504,106 @@ void NavigationObstacle3D::_update_fake_agent_radius_debug() { face_mesh_array[Mesh::ARRAY_VERTEX] = face_vertex_array; face_mesh_array[Mesh::ARRAY_INDEX] = face_indices_array; - fake_agent_radius_debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, face_mesh_array); - Ref<StandardMaterial3D> face_material = NavigationServer3D::get_singleton()->get_debug_navigation_avoidance_obstacles_radius_material(); - fake_agent_radius_debug_mesh->surface_set_material(0, face_material); + rs->mesh_add_surface_from_arrays(fake_agent_radius_debug_mesh_rid, RS::PRIMITIVE_TRIANGLES, face_mesh_array); + + Ref<StandardMaterial3D> face_material = ns3d->get_debug_navigation_avoidance_obstacles_radius_material(); + rs->instance_set_surface_override_material(fake_agent_radius_debug_instance_rid, 0, face_material->get_rid()); - RS::get_singleton()->instance_set_base(fake_agent_radius_debug_instance, fake_agent_radius_debug_mesh->get_rid()); if (is_inside_tree()) { - RS::get_singleton()->instance_set_scenario(fake_agent_radius_debug_instance, get_world_3d()->get_scenario()); - RS::get_singleton()->instance_set_visible(fake_agent_radius_debug_instance, is_visible_in_tree()); + rs->instance_set_scenario(fake_agent_radius_debug_instance_rid, get_world_3d()->get_scenario()); + rs->instance_set_visible(fake_agent_radius_debug_instance_rid, is_visible_in_tree()); } } #endif // DEBUG_ENABLED #ifdef DEBUG_ENABLED void NavigationObstacle3D::_update_static_obstacle_debug() { - bool is_debug_enabled = false; if (Engine::get_singleton()->is_editor_hint()) { - is_debug_enabled = true; - } else if (NavigationServer3D::get_singleton()->get_debug_enabled() && - NavigationServer3D::get_singleton()->get_debug_avoidance_enabled() && - NavigationServer3D::get_singleton()->get_debug_navigation_avoidance_enable_obstacles_static()) { - is_debug_enabled = true; - } - - if (is_debug_enabled == false) { - if (static_obstacle_debug_instance.is_valid()) { - RS::get_singleton()->instance_set_visible(static_obstacle_debug_instance, false); - } + // Don't update inside Editor as Node3D gizmo takes care of this. return; } - if (vertices.size() < 3) { - if (static_obstacle_debug_instance.is_valid()) { - RS::get_singleton()->instance_set_visible(static_obstacle_debug_instance, false); - } - return; - } - - if (!static_obstacle_debug_instance.is_valid()) { - static_obstacle_debug_instance = RenderingServer::get_singleton()->instance_create(); - } - if (!static_obstacle_debug_mesh.is_valid()) { - static_obstacle_debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); - } - static_obstacle_debug_mesh->clear_surfaces(); - - Vector<Vector2> polygon_2d_vertices; - polygon_2d_vertices.resize(vertices.size()); - Vector2 *polygon_2d_vertices_ptr = polygon_2d_vertices.ptrw(); + NavigationServer3D *ns3d = NavigationServer3D::get_singleton(); + RenderingServer *rs = RenderingServer::get_singleton(); - for (int i = 0; i < vertices.size(); ++i) { - Vector3 obstacle_vertex = vertices[i]; - Vector2 obstacle_vertex_2d = Vector2(obstacle_vertex.x, obstacle_vertex.z); - polygon_2d_vertices_ptr[i] = obstacle_vertex_2d; + bool is_debug_enabled = false; + if (ns3d->get_debug_enabled() && + ns3d->get_debug_avoidance_enabled() && + ns3d->get_debug_navigation_avoidance_enable_obstacles_static()) { + is_debug_enabled = true; } - Vector<int> triangulated_polygon_2d_indices = Geometry2D::triangulate_polygon(polygon_2d_vertices); + rs->mesh_clear(static_obstacle_debug_mesh_rid); - if (triangulated_polygon_2d_indices.is_empty()) { - // failed triangulation + if (!is_debug_enabled) { return; } - bool obstacle_pushes_inward = Geometry2D::is_polygon_clockwise(polygon_2d_vertices); + const int vertex_count = vertices.size(); - Vector<Vector3> face_vertex_array; - Vector<int> face_indices_array; - - face_vertex_array.resize(polygon_2d_vertices.size()); - face_indices_array.resize(triangulated_polygon_2d_indices.size()); - - Vector3 *face_vertex_array_ptr = face_vertex_array.ptrw(); - int *face_indices_array_ptr = face_indices_array.ptrw(); - - for (int i = 0; i < triangulated_polygon_2d_indices.size(); ++i) { - int vertex_index = triangulated_polygon_2d_indices[i]; - const Vector2 &vertex_2d = polygon_2d_vertices[vertex_index]; - Vector3 vertex_3d = Vector3(vertex_2d.x, 0.0, vertex_2d.y); - face_vertex_array_ptr[vertex_index] = vertex_3d; - face_indices_array_ptr[i] = vertex_index; + if (vertex_count < 3) { + if (static_obstacle_debug_instance_rid.is_valid()) { + rs->instance_set_visible(static_obstacle_debug_instance_rid, false); + } + return; } - Array face_mesh_array; - face_mesh_array.resize(Mesh::ARRAY_MAX); - face_mesh_array[Mesh::ARRAY_VERTEX] = face_vertex_array; - face_mesh_array[Mesh::ARRAY_INDEX] = face_indices_array; - - static_obstacle_debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, face_mesh_array); - Vector<Vector3> edge_vertex_array; + edge_vertex_array.resize(vertex_count * 8); - for (int i = 0; i < polygon_2d_vertices.size(); ++i) { - int from_index = i - 1; - int to_index = i; + Vector3 *edge_vertex_array_ptrw = edge_vertex_array.ptrw(); - if (i == 0) { - from_index = polygon_2d_vertices.size() - 1; - } + int vertex_index = 0; - const Vector2 &vertex_2d_from = polygon_2d_vertices[from_index]; - const Vector2 &vertex_2d_to = polygon_2d_vertices[to_index]; + for (int i = 0; i < vertex_count; i++) { + Vector3 point = vertices[i]; + Vector3 next_point = vertices[(i + 1) % vertex_count]; - Vector3 vertex_3d_ground_from = Vector3(vertex_2d_from.x, 0.0, vertex_2d_from.y); - Vector3 vertex_3d_ground_to = Vector3(vertex_2d_to.x, 0.0, vertex_2d_to.y); + Vector3 direction = next_point.direction_to(point); + Vector3 arrow_dir = direction.cross(Vector3(0.0, 1.0, 0.0)); + Vector3 edge_middle = point + ((next_point - point) * 0.5); - edge_vertex_array.push_back(vertex_3d_ground_from); - edge_vertex_array.push_back(vertex_3d_ground_to); + edge_vertex_array_ptrw[vertex_index++] = edge_middle; + edge_vertex_array_ptrw[vertex_index++] = edge_middle + (arrow_dir * 0.5); - Vector3 vertex_3d_height_from = Vector3(vertex_2d_from.x, height, vertex_2d_from.y); - Vector3 vertex_3d_height_to = Vector3(vertex_2d_to.x, height, vertex_2d_to.y); + edge_vertex_array_ptrw[vertex_index++] = point; + edge_vertex_array_ptrw[vertex_index++] = next_point; - edge_vertex_array.push_back(vertex_3d_height_from); - edge_vertex_array.push_back(vertex_3d_height_to); + edge_vertex_array_ptrw[vertex_index++] = Vector3(point.x, height, point.z); + edge_vertex_array_ptrw[vertex_index++] = Vector3(next_point.x, height, next_point.z); - edge_vertex_array.push_back(vertex_3d_ground_from); - edge_vertex_array.push_back(vertex_3d_height_from); + edge_vertex_array_ptrw[vertex_index++] = point; + edge_vertex_array_ptrw[vertex_index++] = Vector3(point.x, height, point.z); } Array edge_mesh_array; edge_mesh_array.resize(Mesh::ARRAY_MAX); edge_mesh_array[Mesh::ARRAY_VERTEX] = edge_vertex_array; - static_obstacle_debug_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, edge_mesh_array); + rs->mesh_add_surface_from_arrays(static_obstacle_debug_mesh_rid, RS::PRIMITIVE_LINES, edge_mesh_array); + + Vector<Vector2> polygon_2d_vertices; + polygon_2d_vertices.resize(vertex_count); + for (int i = 0; i < vertex_count; i++) { + const Vector3 &vert = vertices[i]; + polygon_2d_vertices.write[i] = Vector2(vert.x, vert.z); + } + + Vector<int> triangulated_polygon_2d_indices = Geometry2D::triangulate_polygon(polygon_2d_vertices); - Ref<StandardMaterial3D> face_material; Ref<StandardMaterial3D> edge_material; - if (obstacle_pushes_inward) { - face_material = NavigationServer3D::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushin_face_material(); - edge_material = NavigationServer3D::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushin_edge_material(); + if (triangulated_polygon_2d_indices.is_empty()) { + edge_material = ns3d->get_debug_navigation_avoidance_static_obstacle_pushin_edge_material(); } else { - face_material = NavigationServer3D::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushout_face_material(); - edge_material = NavigationServer3D::get_singleton()->get_debug_navigation_avoidance_static_obstacle_pushout_edge_material(); + edge_material = ns3d->get_debug_navigation_avoidance_static_obstacle_pushout_edge_material(); } - static_obstacle_debug_mesh->surface_set_material(0, face_material); - static_obstacle_debug_mesh->surface_set_material(1, edge_material); + rs->instance_set_surface_override_material(static_obstacle_debug_instance_rid, 0, edge_material->get_rid()); - RS::get_singleton()->instance_set_base(static_obstacle_debug_instance, static_obstacle_debug_mesh->get_rid()); if (is_inside_tree()) { - RS::get_singleton()->instance_set_scenario(static_obstacle_debug_instance, get_world_3d()->get_scenario()); - RS::get_singleton()->instance_set_visible(static_obstacle_debug_instance, is_visible_in_tree()); + rs->instance_set_scenario(static_obstacle_debug_instance_rid, get_world_3d()->get_scenario()); + rs->instance_set_visible(static_obstacle_debug_instance_rid, is_visible_in_tree()); } } #endif // DEBUG_ENABLED diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation_obstacle_3d.h index 99288fc59e..99a5770f02 100644 --- a/scene/3d/navigation_obstacle_3d.h +++ b/scene/3d/navigation_obstacle_3d.h @@ -51,8 +51,6 @@ class NavigationObstacle3D : public Node3D { bool use_3d_avoidance = false; - Transform3D previous_transform; - Vector3 velocity; Vector3 previous_velocity; bool velocity_submitted = false; @@ -61,13 +59,14 @@ class NavigationObstacle3D : public Node3D { bool carve_navigation_mesh = false; #ifdef DEBUG_ENABLED - RID fake_agent_radius_debug_instance; - Ref<ArrayMesh> fake_agent_radius_debug_mesh; + RID fake_agent_radius_debug_instance_rid; + RID fake_agent_radius_debug_mesh_rid; - RID static_obstacle_debug_instance; - Ref<ArrayMesh> static_obstacle_debug_mesh; + RID static_obstacle_debug_instance_rid; + RID static_obstacle_debug_mesh_rid; private: + void _update_debug(); void _update_fake_agent_radius_debug(); void _update_static_obstacle_debug(); #endif // DEBUG_ENABLED @@ -117,6 +116,8 @@ public: void set_carve_navigation_mesh(bool p_enabled); bool get_carve_navigation_mesh() const; + PackedStringArray get_configuration_warnings() const override; + private: void _update_map(RID p_map); void _update_position(const Vector3 p_position); diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index c0c254e7ed..2d67e4334e 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -492,8 +492,8 @@ void NavigationRegion3D::_update_debug_mesh() { debug_instance = RenderingServer::get_singleton()->instance_create(); } - if (!debug_mesh.is_valid()) { - debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + if (debug_mesh.is_null()) { + debug_mesh.instantiate(); } debug_mesh->clear_surfaces(); @@ -669,8 +669,8 @@ void NavigationRegion3D::_update_debug_edge_connections_mesh() { debug_edge_connections_instance = RenderingServer::get_singleton()->instance_create(); } - if (!debug_edge_connections_mesh.is_valid()) { - debug_edge_connections_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + if (debug_edge_connections_mesh.is_null()) { + debug_edge_connections_mesh.instantiate(); } debug_edge_connections_mesh->clear_surfaces(); diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index 64259a24b0..00c83101b9 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -88,8 +88,8 @@ void Path3D::_update_debug_mesh() { return; } - if (!debug_mesh.is_valid()) { - debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + if (debug_mesh.is_null()) { + debug_mesh.instantiate(); } if (!(curve.is_valid())) { diff --git a/scene/3d/physics/ray_cast_3d.cpp b/scene/3d/physics/ray_cast_3d.cpp index a9272388c1..b9159f072b 100644 --- a/scene/3d/physics/ray_cast_3d.cpp +++ b/scene/3d/physics/ray_cast_3d.cpp @@ -464,7 +464,7 @@ void RayCast3D::_create_debug_shape() { } if (debug_mesh.is_null()) { - debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + debug_mesh.instantiate(); } } diff --git a/scene/3d/physics/rigid_body_3d.cpp b/scene/3d/physics/rigid_body_3d.cpp index 275e8cd7a9..6c8cea1ac3 100644 --- a/scene/3d/physics/rigid_body_3d.cpp +++ b/scene/3d/physics/rigid_body_3d.cpp @@ -659,7 +659,7 @@ void RigidBody3D::_reload_physics_characteristics() { } PackedStringArray RigidBody3D::get_configuration_warnings() const { - PackedStringArray warnings = CollisionObject3D::get_configuration_warnings(); + PackedStringArray warnings = PhysicsBody3D::get_configuration_warnings(); Vector3 scale = get_transform().get_basis().get_scale(); if (ABS(scale.x - 1.0) > 0.05 || ABS(scale.y - 1.0) > 0.05 || ABS(scale.z - 1.0) > 0.05) { diff --git a/scene/3d/physics/shape_cast_3d.cpp b/scene/3d/physics/shape_cast_3d.cpp index 8ad651fdf5..19c74bc925 100644 --- a/scene/3d/physics/shape_cast_3d.cpp +++ b/scene/3d/physics/shape_cast_3d.cpp @@ -546,7 +546,7 @@ void ShapeCast3D::_create_debug_shape() { } if (debug_mesh.is_null()) { - debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + debug_mesh.instantiate(); } } diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index abece303d1..b51d8a3438 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -1032,6 +1032,10 @@ Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) { return skin_ref; } +void Skeleton3D::force_update_deferred() { + _make_dirty(); +} + void Skeleton3D::force_update_all_dirty_bones() { if (!dirty) { return; diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 90902f71e2..6c51c172af 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -284,6 +284,7 @@ public: void force_update_all_dirty_bones(); void force_update_all_bone_transforms(); void force_update_bone_children_transforms(int bone_idx); + void force_update_deferred(); void set_modifier_callback_mode_process(ModifierCallbackModeProcess p_mode); ModifierCallbackModeProcess get_modifier_callback_mode_process() const; diff --git a/scene/3d/skeleton_modifier_3d.cpp b/scene/3d/skeleton_modifier_3d.cpp index d5c603112e..e8a8e517a2 100644 --- a/scene/3d/skeleton_modifier_3d.cpp +++ b/scene/3d/skeleton_modifier_3d.cpp @@ -75,6 +75,17 @@ void SkeletonModifier3D::_skeleton_changed(Skeleton3D *p_old, Skeleton3D *p_new) // } +void SkeletonModifier3D::_force_update_skeleton_skin() { + if (!is_inside_tree()) { + return; + } + Skeleton3D *skeleton = get_skeleton(); + if (!skeleton) { + return; + } + skeleton->force_update_deferred(); +} + /* Process */ void SkeletonModifier3D::set_active(bool p_active) { @@ -83,6 +94,7 @@ void SkeletonModifier3D::set_active(bool p_active) { } active = p_active; _set_active(active); + _force_update_skeleton_skin(); } bool SkeletonModifier3D::is_active() const { @@ -119,6 +131,10 @@ void SkeletonModifier3D::_notification(int p_what) { case NOTIFICATION_PARENTED: { _update_skeleton(); } break; + case NOTIFICATION_EXIT_TREE: + case NOTIFICATION_UNPARENTED: { + _force_update_skeleton_skin(); + } break; } } diff --git a/scene/3d/skeleton_modifier_3d.h b/scene/3d/skeleton_modifier_3d.h index d00a1e94a9..728b000ff5 100644 --- a/scene/3d/skeleton_modifier_3d.h +++ b/scene/3d/skeleton_modifier_3d.h @@ -50,6 +50,7 @@ protected: void _update_skeleton(); void _update_skeleton_path(); + void _force_update_skeleton_skin(); virtual void _skeleton_changed(Skeleton3D *p_old, Skeleton3D *p_new); diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 42460eec4c..6e3ada83ad 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -470,7 +470,7 @@ Ref<TriangleMesh> SpriteBase3D::generate_triangle_mesh() const { facesw[j] = vtx; } - triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); + triangle_mesh.instantiate(); triangle_mesh->create(faces); return triangle_mesh; diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp index a2aef60417..e172286d05 100644 --- a/scene/animation/animation_blend_tree.cpp +++ b/scene/animation/animation_blend_tree.cpp @@ -93,7 +93,9 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::process(const AnimationMixer AnimationMixer::PlaybackInfo pi = p_playback_info; if (p_playback_info.seeked) { - pi.delta = get_node_time_info().position - p_playback_info.time; + if (p_playback_info.is_external_seeking) { + pi.delta = get_node_time_info().position - p_playback_info.time; + } } else { pi.time = get_node_time_info().position + (backward ? -p_playback_info.delta : p_playback_info.delta); } @@ -140,6 +142,12 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe // 1. Progress for AnimationNode. bool will_end = Animation::is_greater_or_equal_approx(cur_time + cur_delta, cur_len); + bool is_started = p_seek && !p_is_external_seeking && Math::is_zero_approx(cur_time); + + // 1. Progress for AnimationNode. + if (is_started && advance_on_start) { + cur_time = cur_delta; + } if (cur_loop_mode != Animation::LOOP_NONE) { if (cur_loop_mode == Animation::LOOP_LINEAR) { if (!Math::is_zero_approx(cur_len)) { @@ -232,7 +240,7 @@ AnimationNode::NodeTimeInfo AnimationNodeAnimation::_process(const AnimationMixe // We should use call_deferred since the track keys are still being processed. if (process_state->tree && !p_test_only) { // AnimationTree uses seek to 0 "internally" to process the first key of the animation, which is used as the start detection. - if (p_seek && !p_is_external_seeking && Math::is_zero_approx(cur_playback_time)) { + if (is_started) { process_state->tree->call_deferred(SNAME("emit_signal"), SceneStringName(animation_started), animation); } // Finished. @@ -282,6 +290,14 @@ bool AnimationNodeAnimation::is_backward() const { return backward; } +void AnimationNodeAnimation::set_advance_on_start(bool p_advance_on_start) { + advance_on_start = p_advance_on_start; +} + +bool AnimationNodeAnimation::is_advance_on_start() const { + return advance_on_start; +} + void AnimationNodeAnimation::set_use_custom_timeline(bool p_use_custom_timeline) { use_custom_timeline = p_use_custom_timeline; notify_property_list_changed(); @@ -331,6 +347,9 @@ void AnimationNodeAnimation::_bind_methods() { ClassDB::bind_method(D_METHOD("set_play_mode", "mode"), &AnimationNodeAnimation::set_play_mode); ClassDB::bind_method(D_METHOD("get_play_mode"), &AnimationNodeAnimation::get_play_mode); + ClassDB::bind_method(D_METHOD("set_advance_on_start", "advance_on_start"), &AnimationNodeAnimation::set_advance_on_start); + ClassDB::bind_method(D_METHOD("is_advance_on_start"), &AnimationNodeAnimation::is_advance_on_start); + ClassDB::bind_method(D_METHOD("set_use_custom_timeline", "use_custom_timeline"), &AnimationNodeAnimation::set_use_custom_timeline); ClassDB::bind_method(D_METHOD("is_using_custom_timeline"), &AnimationNodeAnimation::is_using_custom_timeline); @@ -348,6 +367,7 @@ void AnimationNodeAnimation::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "animation"), "set_animation", "get_animation"); ADD_PROPERTY(PropertyInfo(Variant::INT, "play_mode", PROPERTY_HINT_ENUM, "Forward,Backward"), "set_play_mode", "get_play_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "advance_on_start"), "set_advance_on_start", "is_advance_on_start"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_custom_timeline"), "set_use_custom_timeline", "is_using_custom_timeline"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "timeline_length", PROPERTY_HINT_RANGE, "0.001,60,0.001,or_greater,or_less,hide_slider,suffix:s"), "set_timeline_length", "get_timeline_length"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stretch_time_scale"), "set_stretch_time_scale", "is_stretching_time_scale"); diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h index 2add35d009..5c912f0095 100644 --- a/scene/animation/animation_blend_tree.h +++ b/scene/animation/animation_blend_tree.h @@ -38,6 +38,8 @@ class AnimationNodeAnimation : public AnimationRootNode { StringName animation; + bool advance_on_start = false; + bool use_custom_timeline = false; double timeline_length = 1.0; Animation::LoopMode loop_mode = Animation::LOOP_NONE; @@ -72,6 +74,9 @@ public: void set_backward(bool p_backward); bool is_backward() const; + void set_advance_on_start(bool p_advance_on_start); + bool is_advance_on_start() const; + void set_use_custom_timeline(bool p_use_custom_timeline); bool is_using_custom_timeline() const; diff --git a/scene/animation/animation_mixer.cpp b/scene/animation/animation_mixer.cpp index 0fa6810d23..b40c677f6e 100644 --- a/scene/animation/animation_mixer.cpp +++ b/scene/animation/animation_mixer.cpp @@ -600,6 +600,22 @@ void AnimationMixer::_init_root_motion_cache() { root_motion_scale_accumulator = Vector3(1, 1, 1); } +void AnimationMixer::_create_track_num_to_track_cashe_for_animation(Ref<Animation> &p_animation) { + ERR_FAIL_COND(animation_track_num_to_track_cashe.has(p_animation)); + LocalVector<TrackCache *> &track_num_to_track_cashe = animation_track_num_to_track_cashe.insert_new(p_animation, LocalVector<TrackCache *>())->value; + const Vector<Animation::Track *> &tracks = p_animation->get_tracks(); + + track_num_to_track_cashe.resize(tracks.size()); + for (int i = 0; i < tracks.size(); i++) { + TrackCache **track_ptr = track_cache.getptr(tracks[i]->thash); + if (track_ptr == nullptr) { + track_num_to_track_cashe[i] = nullptr; + } else { + track_num_to_track_cashe[i] = *track_ptr; + } + } +} + bool AnimationMixer::_update_caches() { setup_pass++; @@ -928,20 +944,9 @@ bool AnimationMixer::_update_caches() { } animation_track_num_to_track_cashe.clear(); - LocalVector<TrackCache *> track_num_to_track_cashe; for (const StringName &E : sname_list) { Ref<Animation> anim = get_animation(E); - const Vector<Animation::Track *> tracks = anim->get_tracks(); - track_num_to_track_cashe.resize(tracks.size()); - for (int i = 0; i < tracks.size(); i++) { - TrackCache **track_ptr = track_cache.getptr(tracks[i]->thash); - if (track_ptr == nullptr) { - track_num_to_track_cashe[i] = nullptr; - } else { - track_num_to_track_cashe[i] = *track_ptr; - } - } - animation_track_num_to_track_cashe.insert(anim, track_num_to_track_cashe); + _create_track_num_to_track_cashe_for_animation(anim); } track_count = idx; @@ -1074,6 +1079,9 @@ void AnimationMixer::blend_capture(double p_delta) { capture_cache.remain -= p_delta * capture_cache.step; if (Animation::is_less_or_equal_approx(capture_cache.remain, 0)) { + if (capture_cache.animation.is_valid()) { + animation_track_num_to_track_cashe.erase(capture_cache.animation); + } capture_cache.clear(); return; } @@ -2205,6 +2213,9 @@ void AnimationMixer::capture(const StringName &p_name, double p_duration, Tween: capture_cache.step = 1.0 / p_duration; capture_cache.trans_type = p_trans_type; capture_cache.ease_type = p_ease_type; + if (capture_cache.animation.is_valid()) { + animation_track_num_to_track_cashe.erase(capture_cache.animation); + } capture_cache.animation.instantiate(); bool is_valid = false; @@ -2228,6 +2239,8 @@ void AnimationMixer::capture(const StringName &p_name, double p_duration, Tween: } if (!is_valid) { capture_cache.clear(); + } else { + _create_track_num_to_track_cashe_for_animation(capture_cache.animation); } } diff --git a/scene/animation/animation_mixer.h b/scene/animation/animation_mixer.h index 1906146c56..3769fa268c 100644 --- a/scene/animation/animation_mixer.h +++ b/scene/animation/animation_mixer.h @@ -321,6 +321,7 @@ protected: void _clear_playing_caches(); void _init_root_motion_cache(); bool _update_caches(); + void _create_track_num_to_track_cashe_for_animation(Ref<Animation> &p_animation); /* ---- Audio ---- */ AudioServer::PlaybackType playback_type; diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index d676e2acf4..f2871cda79 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -371,7 +371,9 @@ AnimationNode::NodeTimeInfo AnimationNode::process(const AnimationMixer::Playbac AnimationMixer::PlaybackInfo pi = p_playback_info; if (p_playback_info.seeked) { - pi.delta = get_node_time_info().position - p_playback_info.time; + if (p_playback_info.is_external_seeking) { + pi.delta = get_node_time_info().position - p_playback_info.time; + } } else { pi.time = get_node_time_info().position + p_playback_info.delta; } diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index eb25a8db1b..5a2a822ff0 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -91,7 +91,7 @@ public: if (Math::is_zero_approx(remain)) { return 0; } - return length - position; + return remain; } }; diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 34f5095493..bd4770bcc3 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -205,6 +205,7 @@ void BaseButton::set_disabled(bool p_disabled) { status.pressing_inside = false; } queue_redraw(); + update_minimum_size(); } bool BaseButton::is_disabled() const { diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 9d7e2496a2..89f1564775 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -1498,9 +1498,9 @@ void CodeEdit::_line_number_draw_callback(int p_line, int p_gutter, const Rect2 ofs.y += TS->shaped_text_get_ascent(text_rid); if (rtl) { - ofs.x = p_region.position.x; - } else { ofs.x = p_region.get_end().x - text_size.width; + } else { + ofs.x = p_region.position.x; } Color number_color = get_line_gutter_item_color(p_line, line_number_gutter); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index b1c47d858d..7e07f4a202 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -3001,5 +3001,5 @@ GraphEdit::GraphEdit() { set_clip_contents(true); - arranger = Ref<GraphEditArranger>(memnew(GraphEditArranger(this))); + arranger.instantiate(this); } diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 79018c40f5..26d164a62d 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -178,7 +178,7 @@ bool OptionButton::_set(const StringName &p_name, const Variant &p_value) { } void OptionButton::_focused(int p_which) { - emit_signal(SNAME("item_focused"), p_which); + emit_signal(SNAME("item_focused"), popup->get_item_index(p_which)); } void OptionButton::_selected(int p_which) { diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 3c04094526..f6ebcc854c 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -474,7 +474,7 @@ void PopupMenu::_input_from_window_internal(const Ref<InputEvent> &p_event) { for (int i = search_from; i < items.size(); i++) { if (!items[i].separator && !items[i].disabled) { mouse_over = i; - emit_signal(SNAME("id_focused"), i); + emit_signal(SNAME("id_focused"), items[i].id); scroll_to_item(i); control->queue_redraw(); set_input_as_handled(); @@ -488,7 +488,7 @@ void PopupMenu::_input_from_window_internal(const Ref<InputEvent> &p_event) { for (int i = 0; i < search_from; i++) { if (!items[i].separator && !items[i].disabled) { mouse_over = i; - emit_signal(SNAME("id_focused"), i); + emit_signal(SNAME("id_focused"), items[i].id); scroll_to_item(i); control->queue_redraw(); set_input_as_handled(); @@ -512,7 +512,7 @@ void PopupMenu::_input_from_window_internal(const Ref<InputEvent> &p_event) { for (int i = search_from; i >= 0; i--) { if (!items[i].separator && !items[i].disabled) { mouse_over = i; - emit_signal(SNAME("id_focused"), i); + emit_signal(SNAME("id_focused"), items[i].id); scroll_to_item(i); control->queue_redraw(); set_input_as_handled(); @@ -526,7 +526,7 @@ void PopupMenu::_input_from_window_internal(const Ref<InputEvent> &p_event) { for (int i = items.size() - 1; i >= search_from; i--) { if (!items[i].separator && !items[i].disabled) { mouse_over = i; - emit_signal(SNAME("id_focused"), i); + emit_signal(SNAME("id_focused"), items[i].id); scroll_to_item(i); control->queue_redraw(); set_input_as_handled(); @@ -692,7 +692,7 @@ void PopupMenu::_input_from_window_internal(const Ref<InputEvent> &p_event) { if (items[i].text.findn(search_string) == 0) { mouse_over = i; - emit_signal(SNAME("id_focused"), i); + emit_signal(SNAME("id_focused"), items[i].id); scroll_to_item(i); control->queue_redraw(); set_input_as_handled(); @@ -1091,7 +1091,7 @@ void PopupMenu::_notification(int p_what) { for (int i = search_from; i < items.size(); i++) { if (!items[i].separator && !items[i].disabled) { mouse_over = i; - emit_signal(SNAME("id_focused"), i); + emit_signal(SNAME("id_focused"), items[i].id); scroll_to_item(i); control->queue_redraw(); match_found = true; @@ -1104,7 +1104,7 @@ void PopupMenu::_notification(int p_what) { for (int i = 0; i < search_from; i++) { if (!items[i].separator && !items[i].disabled) { mouse_over = i; - emit_signal(SNAME("id_focused"), i); + emit_signal(SNAME("id_focused"), items[i].id); scroll_to_item(i); control->queue_redraw(); break; @@ -1124,7 +1124,7 @@ void PopupMenu::_notification(int p_what) { for (int i = search_from; i >= 0; i--) { if (!items[i].separator && !items[i].disabled) { mouse_over = i; - emit_signal(SNAME("id_focused"), i); + emit_signal(SNAME("id_focused"), items[i].id); scroll_to_item(i); control->queue_redraw(); match_found = true; @@ -1137,7 +1137,7 @@ void PopupMenu::_notification(int p_what) { for (int i = items.size() - 1; i >= search_from; i--) { if (!items[i].separator && !items[i].disabled) { mouse_over = i; - emit_signal(SNAME("id_focused"), i); + emit_signal(SNAME("id_focused"), items[i].id); scroll_to_item(i); control->queue_redraw(); break; diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index 01c2b9bffe..e56a9e71ef 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -41,7 +41,11 @@ Size2 SpinBox::get_minimum_size() const { } void SpinBox::_update_text(bool p_keep_line_edit) { - String value = String::num(get_value(), Math::range_step_decimals(get_step())); + double step = get_step(); + if (use_custom_arrow_step && custom_arrow_step != 0.0) { + step = custom_arrow_step; + } + String value = String::num(get_value(), Math::range_step_decimals(step)); if (is_localizing_numeral_system()) { value = TS->format_number(value); } @@ -75,6 +79,9 @@ void SpinBox::_text_submitted(const String &p_string) { text = text.trim_prefix(prefix + " ").trim_suffix(" " + suffix); Error err = expr->parse(text); + + use_custom_arrow_step = false; + if (err != OK) { // If the expression failed try without converting commas to dots - they might have been for parameter separation. text = p_string; @@ -114,8 +121,13 @@ void SpinBox::_line_edit_input(const Ref<InputEvent> &p_event) { void SpinBox::_range_click_timeout() { if (!drag.enabled && Input::get_singleton()->is_mouse_button_pressed(MouseButton::LEFT)) { bool up = get_local_mouse_position().y < (get_size().height / 2); - double step = get_custom_arrow_step() != 0.0 ? get_custom_arrow_step() : get_step(); - set_value(get_value() + (up ? step : -step)); + double step = get_step(); + // Arrow button is being pressed, so we also need to set the step to the same value as custom_arrow_step if its not 0. + double temp_step = get_custom_arrow_step() != 0.0 ? get_custom_arrow_step() : get_step(); + _set_step_no_signal(temp_step); + set_value(get_value() + (up ? temp_step : -temp_step)); + _set_step_no_signal(step); + use_custom_arrow_step = true; if (range_click_timer->is_one_shot()) { range_click_timer->set_wait_time(0.075); @@ -156,8 +168,7 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; Ref<InputEventMouseMotion> mm = p_event; - double step = get_custom_arrow_step() != 0.0 ? get_custom_arrow_step() : get_step(); - + double step = get_step(); Vector2 mpos; bool mouse_on_up_button = false; bool mouse_on_down_button = false; @@ -177,7 +188,12 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) { line_edit->grab_focus(); if (mouse_on_up_button || mouse_on_down_button) { - set_value(get_value() + (mouse_on_up_button ? step : -step)); + // Arrow button is being pressed, so step is being changed temporarily. + double temp_step = get_custom_arrow_step() != 0.0 ? get_custom_arrow_step() : get_step(); + _set_step_no_signal(temp_step); + set_value(get_value() + (mouse_on_up_button ? temp_step : -temp_step)); + _set_step_no_signal(step); + use_custom_arrow_step = true; } state_cache.up_button_pressed = mouse_on_up_button; state_cache.down_button_pressed = mouse_on_down_button; @@ -193,17 +209,20 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) { case MouseButton::RIGHT: { line_edit->grab_focus(); if (mouse_on_up_button || mouse_on_down_button) { + use_custom_arrow_step = false; set_value(mouse_on_up_button ? get_max() : get_min()); } } break; case MouseButton::WHEEL_UP: { if (line_edit->is_editing()) { + use_custom_arrow_step = false; set_value(get_value() + step * mb->get_factor()); accept_event(); } } break; case MouseButton::WHEEL_DOWN: { if (line_edit->is_editing()) { + use_custom_arrow_step = false; set_value(get_value() - step * mb->get_factor()); accept_event(); } @@ -243,6 +262,7 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) { if (drag.enabled) { drag.diff_y += mm->get_relative().y; double diff_y = -0.01 * Math::pow(ABS(drag.diff_y), 1.8) * SIGN(drag.diff_y); + use_custom_arrow_step = false; set_value(CLAMP(drag.base_val + step * diff_y, get_min(), get_max())); } else if (drag.allowed && drag.capture_pos.distance_to(mm->get_position()) > 2) { Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED); @@ -519,6 +539,12 @@ void SpinBox::_update_buttons_state_for_current_value() { } } +void SpinBox::_set_step_no_signal(double p_step) { + set_block_signals(true); + set_step(p_step); + set_block_signals(false); +} + void SpinBox::_bind_methods() { ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &SpinBox::set_horizontal_alignment); ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &SpinBox::get_horizontal_alignment); diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index 294dc3e5d5..06a0f622b9 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -66,6 +66,7 @@ class SpinBox : public Range { String suffix; String last_updated_text; double custom_arrow_step = 0.0; + bool use_custom_arrow_step = false; void _line_edit_input(const Ref<InputEvent> &p_event); @@ -133,6 +134,7 @@ class SpinBox : public Range { void _mouse_exited(); void _update_buttons_state_for_current_value(); + void _set_step_no_signal(double p_step); protected: virtual void gui_input(const Ref<InputEvent> &p_event) override; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index b1918ff23f..05e9b84bfa 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -332,6 +332,7 @@ void TextEdit::Text::clear() { max_line_width_dirty = true; max_line_height_dirty = true; + total_visible_line_count = 0; Line line; line.gutters.resize(gutter_count); @@ -421,6 +422,10 @@ void TextEdit::Text::remove_range(int p_from_line, int p_to_line) { for (int i = p_from_line; i < p_to_line; i++) { const Line &text_line = text[i]; + if (text_line.hidden) { + continue; + } + if (text_line.height == max_line_height) { max_line_height_dirty = true; } @@ -435,6 +440,8 @@ void TextEdit::Text::remove_range(int p_from_line, int p_to_line) { text.write[(i - diff) + 1] = text[i + 1]; } text.resize(text.size() - diff); + + ERR_FAIL_COND(total_visible_line_count < 0); // BUG } void TextEdit::Text::add_gutter(int p_at) { @@ -7303,6 +7310,10 @@ void TextEdit::_paste_internal(int p_caret) { } String clipboard = DisplayServer::get_singleton()->clipboard_get(); + if (clipboard.is_empty()) { + // Nothing to paste. + return; + } // Paste a full line. Ignore '\r' characters that may have been added to the clipboard by the OS. if (get_caret_count() == 1 && !has_selection(0) && !cut_copy_line.is_empty() && cut_copy_line == clipboard.replace("\r", "")) { diff --git a/scene/main/missing_node.cpp b/scene/main/missing_node.cpp index 83672ae5e0..d5a183eab1 100644 --- a/scene/main/missing_node.cpp +++ b/scene/main/missing_node.cpp @@ -84,17 +84,17 @@ bool MissingNode::is_recording_properties() const { PackedStringArray MissingNode::get_configuration_warnings() const { // The mere existence of this node is warning. - PackedStringArray ret; + PackedStringArray warnings = Node::get_configuration_warnings(); if (!original_scene.is_empty()) { - ret.push_back(vformat(RTR("This node was an instance of scene '%s', which was no longer available when this scene was loaded."), original_scene)); - ret.push_back(vformat(RTR("Saving current scene will discard instance and all its properties, including editable children edits (if existing)."))); + warnings.push_back(vformat(RTR("This node was an instance of scene '%s', which was no longer available when this scene was loaded."), original_scene)); + warnings.push_back(vformat(RTR("Saving current scene will discard instance and all its properties, including editable children edits (if existing)."))); } else if (!original_class.is_empty()) { - ret.push_back(vformat(RTR("This node was saved as class type '%s', which was no longer available when this scene was loaded."), original_class)); - ret.push_back(RTR("Data from the original node is kept as a placeholder until this type of node is available again. It can hence be safely re-saved without risk of data loss.")); + warnings.push_back(vformat(RTR("This node was saved as class type '%s', which was no longer available when this scene was loaded."), original_class)); + warnings.push_back(RTR("Data from the original node is kept as a placeholder until this type of node is available again. It can hence be safely re-saved without risk of data loss.")); } else { - ret.push_back(RTR("Unrecognized missing node. Check scene dependency errors for details.")); + warnings.push_back(RTR("Unrecognized missing node. Check scene dependency errors for details.")); } - return ret; + return warnings; } void MissingNode::_bind_methods() { diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 8dc7b4a87c..5063f0d6d0 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -3055,11 +3055,12 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const { if (copy && copytarget && E.callable.get_method() != StringName()) { Callable copy_callable = Callable(copytarget, E.callable.get_method()); if (!copy->is_connected(E.signal.get_name(), copy_callable)) { - int arg_count = E.callable.get_bound_arguments_count(); - if (arg_count > 0) { + int unbound_arg_count = E.callable.get_unbound_arguments_count(); + if (unbound_arg_count > 0) { + copy_callable = copy_callable.unbind(unbound_arg_count); + } + if (E.callable.get_bound_arguments_count() > 0) { copy_callable = copy_callable.bindv(E.callable.get_bound_arguments()); - } else if (arg_count < 0) { - copy_callable = copy_callable.unbind(-arg_count); } copy->connect(E.signal.get_name(), copy_callable, E.flags); } diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 60cecfcfe7..16b41c8f9b 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -899,7 +899,7 @@ Ref<ArrayMesh> SceneTree::get_debug_contact_mesh() { return debug_contact_mesh; } - debug_contact_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + debug_contact_mesh.instantiate(); Ref<StandardMaterial3D> mat = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 5a90eb8f3e..1ee99099ec 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1213,7 +1213,7 @@ void Viewport::set_world_2d(const Ref<World2D> &p_world_2d) { } } else { WARN_PRINT("Invalid world_2d"); - world_2d = Ref<World2D>(memnew(World2D)); + world_2d.instantiate(); } world_2d->register_viewport(this); @@ -4386,7 +4386,7 @@ void Viewport::set_world_3d(const Ref<World3D> &p_world_3d) { own_world_3d = world_3d->duplicate(); world_3d->connect_changed(callable_mp(this, &Viewport::_own_world_3d_changed)); } else { - own_world_3d = Ref<World3D>(memnew(World3D)); + own_world_3d.instantiate(); } } @@ -4437,7 +4437,7 @@ void Viewport::set_use_own_world_3d(bool p_use_own_world_3d) { own_world_3d = world_3d->duplicate(); world_3d->connect_changed(callable_mp(this, &Viewport::_own_world_3d_changed)); } else { - own_world_3d = Ref<World3D>(memnew(World3D)); + own_world_3d.instantiate(); } } else { own_world_3d = Ref<World3D>(); @@ -4963,7 +4963,7 @@ void Viewport::_validate_property(PropertyInfo &p_property) const { } Viewport::Viewport() { - world_2d = Ref<World2D>(memnew(World2D)); + world_2d.instantiate(); world_2d->register_viewport(this); viewport = RenderingServer::get_singleton()->viewport_create(); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 315ccaeb8c..8a048e9cc3 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -243,6 +243,7 @@ #include "scene/3d/light_3d.h" #include "scene/3d/lightmap_gi.h" #include "scene/3d/lightmap_probe.h" +#include "scene/3d/look_at_modifier_3d.h" #include "scene/3d/marker_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/multimesh_instance_3d.h" @@ -611,6 +612,7 @@ void register_scene_types() { GDREGISTER_CLASS(SkeletonIK3D); GDREGISTER_CLASS(BoneAttachment3D); + GDREGISTER_CLASS(LookAtModifier3D); GDREGISTER_CLASS(VehicleBody3D); GDREGISTER_CLASS(VehicleWheel3D); diff --git a/scene/resources/2d/navigation_mesh_source_geometry_data_2d.h b/scene/resources/2d/navigation_mesh_source_geometry_data_2d.h index b29c106fb5..2812925770 100644 --- a/scene/resources/2d/navigation_mesh_source_geometry_data_2d.h +++ b/scene/resources/2d/navigation_mesh_source_geometry_data_2d.h @@ -36,6 +36,8 @@ #include "scene/resources/2d/navigation_polygon.h" class NavigationMeshSourceGeometryData2D : public Resource { + friend class NavMeshGenerator2D; + GDCLASS(NavigationMeshSourceGeometryData2D, Resource); RWLock geometry_rwlock; diff --git a/scene/resources/3d/shape_3d.cpp b/scene/resources/3d/shape_3d.cpp index 5a79392ba5..259d82b7a0 100644 --- a/scene/resources/3d/shape_3d.cpp +++ b/scene/resources/3d/shape_3d.cpp @@ -73,7 +73,7 @@ Ref<ArrayMesh> Shape3D::get_debug_mesh() { Vector<Vector3> lines = get_debug_mesh_lines(); - debug_mesh_cache = Ref<ArrayMesh>(memnew(ArrayMesh)); + debug_mesh_cache.instantiate(); if (!lines.is_empty()) { //make mesh diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index 8926eb1d51..765373ce99 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -479,6 +479,9 @@ void Curve::set_bake_resolution(int p_resolution) { } real_t Curve::sample_baked(real_t p_offset) const { + // Make sure that p_offset is finite. + ERR_FAIL_COND_V_MSG(!Math::is_finite(p_offset), 0, "Offset is non-finite"); + if (_baked_cache_dirty) { // Last-second bake if not done already const_cast<Curve *>(this)->bake(); @@ -981,6 +984,9 @@ Transform2D Curve2D::_sample_posture(Interval p_interval) const { } Vector2 Curve2D::sample_baked(real_t p_offset, bool p_cubic) const { + // Make sure that p_offset is finite. + ERR_FAIL_COND_V_MSG(!Math::is_finite(p_offset), Vector2(), "Offset is non-finite"); + if (baked_cache_dirty) { _bake(); } @@ -1000,6 +1006,9 @@ Vector2 Curve2D::sample_baked(real_t p_offset, bool p_cubic) const { } Transform2D Curve2D::sample_baked_with_rotation(real_t p_offset, bool p_cubic) const { + // Make sure that p_offset is finite. + ERR_FAIL_COND_V_MSG(!Math::is_finite(p_offset), Transform2D(), "Offset is non-finite"); + if (baked_cache_dirty) { _bake(); } @@ -1881,6 +1890,9 @@ Basis Curve3D::get_point_baked_posture(int p_index, bool p_apply_tilt) const { #endif Vector3 Curve3D::sample_baked(real_t p_offset, bool p_cubic) const { + // Make sure that p_offset is finite. + ERR_FAIL_COND_V_MSG(!Math::is_finite(p_offset), Vector3(), "Offset is non-finite"); + if (baked_cache_dirty) { _bake(); } @@ -1900,6 +1912,9 @@ Vector3 Curve3D::sample_baked(real_t p_offset, bool p_cubic) const { } Transform3D Curve3D::sample_baked_with_rotation(real_t p_offset, bool p_cubic, bool p_apply_tilt) const { + // Make sure that p_offset is finite. + ERR_FAIL_COND_V_MSG(!Math::is_finite(p_offset), Transform3D(), "Offset is non-finite"); + if (baked_cache_dirty) { _bake(); } @@ -1929,6 +1944,9 @@ Transform3D Curve3D::sample_baked_with_rotation(real_t p_offset, bool p_cubic, b } real_t Curve3D::sample_baked_tilt(real_t p_offset) const { + // Make sure that p_offset is finite. + ERR_FAIL_COND_V_MSG(!Math::is_finite(p_offset), 0, "Offset is non-finite"); + if (baked_cache_dirty) { _bake(); } @@ -1948,6 +1966,9 @@ real_t Curve3D::sample_baked_tilt(real_t p_offset) const { } Vector3 Curve3D::sample_baked_up_vector(real_t p_offset, bool p_apply_tilt) const { + // Make sure that p_offset is finite. + ERR_FAIL_COND_V_MSG(!Math::is_finite(p_offset), Vector3(0, 1, 0), "Offset is non-finite"); + if (baked_cache_dirty) { _bake(); } diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 848ae2713d..b0353b4f2c 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -385,7 +385,7 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { } } - triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); + triangle_mesh.instantiate(); triangle_mesh->create(faces); return triangle_mesh; diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp index 67ed65df0d..034d4d6996 100644 --- a/scene/resources/navigation_mesh.cpp +++ b/scene/resources/navigation_mesh.cpp @@ -392,8 +392,8 @@ Ref<ArrayMesh> NavigationMesh::get_debug_mesh() { return debug_mesh; } - if (!debug_mesh.is_valid()) { - debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh)); + if (debug_mesh.is_null()) { + debug_mesh.instantiate(); } else { debug_mesh->clear_surfaces(); } diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index bb3aad0f28..809a77a487 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -2195,7 +2195,7 @@ void PackedScene::replace_state(Ref<SceneState> p_by) { } void PackedScene::recreate_state() { - state = Ref<SceneState>(memnew(SceneState)); + state.instantiate(); state->set_path(get_path()); #ifdef TOOLS_ENABLED state->set_last_modified_time(get_last_modified_time()); @@ -2286,5 +2286,5 @@ void PackedScene::_bind_methods() { } PackedScene::PackedScene() { - state = Ref<SceneState>(memnew(SceneState)); + state.instantiate(); } diff --git a/scene/resources/portable_compressed_texture.cpp b/scene/resources/portable_compressed_texture.cpp index 06b5ec6d5a..55bbed7c47 100644 --- a/scene/resources/portable_compressed_texture.cpp +++ b/scene/resources/portable_compressed_texture.cpp @@ -89,7 +89,7 @@ void PortableCompressedTexture2D::_set_data(const Vector<uint8_t> &p_data) { data_size -= mipsize; } - image = Ref<Image>(memnew(Image(size.width, size.height, mipmaps, format, image_data))); + image.instantiate(size.width, size.height, mipmaps, format, image_data); } break; case COMPRESSION_MODE_BASIS_UNIVERSAL: { @@ -100,7 +100,7 @@ void PortableCompressedTexture2D::_set_data(const Vector<uint8_t> &p_data) { case COMPRESSION_MODE_S3TC: case COMPRESSION_MODE_ETC2: case COMPRESSION_MODE_BPTC: { - image = Ref<Image>(memnew(Image(size.width, size.height, mipmaps, format, p_data.slice(20)))); + image.instantiate(size.width, size.height, mipmaps, format, p_data.slice(20)); } break; } ERR_FAIL_COND(image.is_null()); diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 535903a1b6..6e03fe25c9 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -1526,6 +1526,10 @@ ResourceUID::ID ResourceFormatLoaderText::get_resource_uid(const String &p_path) return loader.get_uid(f); } +bool ResourceFormatLoaderText::has_custom_uid_support() const { + return true; +} + void ResourceFormatLoaderText::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); if (f.is_null()) { diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h index 8397bc985f..4c0bf3d917 100644 --- a/scene/resources/resource_format_text.h +++ b/scene/resources/resource_format_text.h @@ -155,6 +155,7 @@ public: virtual String get_resource_type(const String &p_path) const override; virtual String get_resource_script_class(const String &p_path) const override; virtual ResourceUID::ID get_resource_uid(const String &p_path) const override; + virtual bool has_custom_uid_support() const override; virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false) override; virtual Error rename_dependencies(const String &p_path, const HashMap<String, String> &p_map) override; diff --git a/scene/resources/texture_rd.cpp b/scene/resources/texture_rd.cpp index 531dbcbe7e..8e7eeb0ff4 100644 --- a/scene/resources/texture_rd.cpp +++ b/scene/resources/texture_rd.cpp @@ -197,7 +197,7 @@ void TextureLayeredRD::_set_texture_rd_rid(RID p_texture_rd_rid) { RS::TextureLayeredType rs_layer_type; RD::TextureFormat tf = RD::get_singleton()->texture_get_format(p_texture_rd_rid); - ERR_FAIL_COND(tf.texture_type != RD::TEXTURE_TYPE_2D_ARRAY); + ERR_FAIL_COND(tf.texture_type != RD::TEXTURE_TYPE_2D_ARRAY && tf.texture_type != RD::TEXTURE_TYPE_CUBE && tf.texture_type != RD::TEXTURE_TYPE_CUBE_ARRAY); ERR_FAIL_COND(tf.depth > 1); switch (layer_type) { case LAYERED_TYPE_2D_ARRAY: { diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index 42fce65b2d..8a9499dfc9 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -1666,7 +1666,9 @@ void TextureStorage::texture_rd_initialize(RID p_texture, const RID &p_rd_textur ERR_FAIL_COND(tf.array_layers != 1); texture.type = TextureStorage::TYPE_2D; } break; - case RD::TEXTURE_TYPE_2D_ARRAY: { + case RD::TEXTURE_TYPE_2D_ARRAY: + case RD::TEXTURE_TYPE_CUBE: + case RD::TEXTURE_TYPE_CUBE_ARRAY: { // RenderingDevice doesn't distinguish between Array textures and Cube textures // this condition covers TextureArrays, TextureCube, and TextureCubeArray. ERR_FAIL_COND(tf.array_layers == 1); diff --git a/servers/rendering/rendering_device_graph.cpp b/servers/rendering/rendering_device_graph.cpp index ec2f336f3c..86b5f80e56 100644 --- a/servers/rendering/rendering_device_graph.cpp +++ b/servers/rendering/rendering_device_graph.cpp @@ -140,7 +140,7 @@ RDD::BarrierAccessBits RenderingDeviceGraph::_usage_to_access_bits(ResourceUsage #endif } -bool RenderingDeviceGraph::_check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index) const { +bool RenderingDeviceGraph::_check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index, bool &r_intersection_partial_coverage) const { if (p_resource_tracker->usage != RESOURCE_USAGE_ATTACHMENT_COLOR_READ_WRITE && p_resource_tracker->usage != RESOURCE_USAGE_ATTACHMENT_DEPTH_STENCIL_READ_WRITE) { // We don't check possible intersections for usages that aren't consecutive color or depth writes. return true; @@ -155,6 +155,11 @@ bool RenderingDeviceGraph::_check_command_intersection(ResourceTracker *p_resour return true; } + if (!r_intersection_partial_coverage) { + // Indicate if this draw list only partially covers the region of the previous draw list. + r_intersection_partial_coverage = !current_draw_list_command.region.encloses(previous_draw_list_command.region); + } + // We check if the region used by both draw lists have an intersection. return previous_draw_list_command.region.intersects(current_draw_list_command.region); } @@ -471,7 +476,7 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr resource_tracker->usage = new_resource_usage; } - bool command_intersection_failed = false; + bool intersection_partial_coverage = false; if (search_tracker->write_command_or_list_index >= 0) { if (search_tracker->write_command_list_enabled) { // Make this command adjacent to any commands that wrote to this resource and intersect with the slice if it applies. @@ -483,7 +488,7 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr if (!resource_has_parent || search_tracker_rect.intersects(write_list_node.subresources)) { if (write_list_node.command_index == p_command_index) { ERR_FAIL_COND_MSG(!resource_has_parent, "Command can't have itself as a dependency."); - } else if (_check_command_intersection(resource_tracker, write_list_node.command_index, p_command_index)) { + } else if (_check_command_intersection(resource_tracker, write_list_node.command_index, p_command_index, intersection_partial_coverage)) { // Command is dependent on this command. Add this command to the adjacency list of the write command. _add_adjacent_command(write_list_node.command_index, p_command_index, r_command); @@ -499,8 +504,6 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr write_list_index = write_list_node.next_list_index; continue; } - } else { - command_intersection_failed = true; } } @@ -511,16 +514,14 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr // The index is just the latest command index that wrote to the resource. if (search_tracker->write_command_or_list_index == p_command_index) { ERR_FAIL_MSG("Command can't have itself as a dependency."); - } else if (_check_command_intersection(resource_tracker, search_tracker->write_command_or_list_index, p_command_index)) { + } else if (_check_command_intersection(resource_tracker, search_tracker->write_command_or_list_index, p_command_index, intersection_partial_coverage)) { _add_adjacent_command(search_tracker->write_command_or_list_index, p_command_index, r_command); - } else { - command_intersection_failed = true; } } } if (write_usage) { - if (resource_has_parent || command_intersection_failed) { + if (resource_has_parent || intersection_partial_coverage) { if (!search_tracker->write_command_list_enabled && search_tracker->write_command_or_list_index >= 0) { // Write command list was not being used but there was a write command recorded. Add a new node with the entire parent resource's subresources and the recorded command index to the list. const RDD::TextureSubresourceRange &tracker_subresources = search_tracker->texture_subresources; diff --git a/servers/rendering/rendering_device_graph.h b/servers/rendering/rendering_device_graph.h index 9ddd70bc80..452e1700b6 100644 --- a/servers/rendering/rendering_device_graph.h +++ b/servers/rendering/rendering_device_graph.h @@ -649,7 +649,7 @@ private: static bool _is_write_usage(ResourceUsage p_usage); static RDD::TextureLayout _usage_to_image_layout(ResourceUsage p_usage); static RDD::BarrierAccessBits _usage_to_access_bits(ResourceUsage p_usage); - bool _check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index) const; + bool _check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index, bool &r_intersection_partial_coverage) const; int32_t _add_to_command_list(int32_t p_command_index, int32_t p_list_index); void _add_adjacent_command(int32_t p_previous_command_index, int32_t p_command_index, RecordedCommand *r_command); int32_t _add_to_slice_read_list(int32_t p_command_index, Rect2i p_subresources, int32_t p_list_index); diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp index 119ac677eb..f52963f98f 100644 --- a/servers/rendering/shader_compiler.cpp +++ b/servers/rendering/shader_compiler.cpp @@ -489,7 +489,7 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene struct_code += _typestr(m->datatype); } struct_code += " "; - struct_code += m->name; + struct_code += _mkid(m->name); if (m->array_size > 0) { struct_code += "["; struct_code += itos(m->array_size); @@ -1448,7 +1448,13 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene } break; case SL::Node::NODE_TYPE_MEMBER: { SL::MemberNode *mnode = (SL::MemberNode *)p_node; - code = _dump_node_code(mnode->owner, p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + "." + mnode->name; + String name; + if (mnode->basetype == SL::TYPE_STRUCT) { + name = _mkid(mnode->name); + } else { + name = mnode->name; + } + code = _dump_node_code(mnode->owner, p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + "." + name; if (mnode->index_expression != nullptr) { code += "["; code += _dump_node_code(mnode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 272908aa49..c0c6f1e904 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2067,6 +2067,16 @@ void RenderingServer::_particles_set_trail_bind_poses(RID p_particles, const Typ particles_set_trail_bind_poses(p_particles, tbposes); } +String RenderingServer::get_current_rendering_driver_name() const { + // Needs to remain in OS, since it's actually OS that interacts with it, but it's better exposed here. + return ::OS::get_singleton()->get_current_rendering_driver_name(); +} + +String RenderingServer::get_current_rendering_method() const { + // Needs to remain in OS, since it's actually OS that interacts with it, but it's better exposed here. + return ::OS::get_singleton()->get_current_rendering_method(); +} + Vector<uint8_t> _convert_surface_version_1_to_surface_version_2(uint64_t p_format, Vector<uint8_t> p_vertex_data, uint32_t p_vertex_count, uint32_t p_old_stride, uint32_t p_vertex_size, uint32_t p_normal_size, uint32_t p_position_stride, uint32_t p_normal_tangent_stride) { Vector<uint8_t> new_vertex_data; new_vertex_data.resize(p_vertex_data.size()); @@ -3423,6 +3433,9 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_video_adapter_type"), &RenderingServer::get_video_adapter_type); ClassDB::bind_method(D_METHOD("get_video_adapter_api_version"), &RenderingServer::get_video_adapter_api_version); + ClassDB::bind_method(D_METHOD("get_current_rendering_driver_name"), &RenderingServer::get_current_rendering_driver_name); + ClassDB::bind_method(D_METHOD("get_current_rendering_method"), &RenderingServer::get_current_rendering_method); + ClassDB::bind_method(D_METHOD("make_sphere_mesh", "latitudes", "longitudes", "radius"), &RenderingServer::make_sphere_mesh); ClassDB::bind_method(D_METHOD("get_test_cube"), &RenderingServer::get_test_cube); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 90365a19eb..6de934aaeb 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -1787,6 +1787,9 @@ public: virtual bool is_on_render_thread() = 0; virtual void call_on_render_thread(const Callable &p_callable) = 0; + String get_current_rendering_driver_name() const; + String get_current_rendering_method() const; + #ifdef TOOLS_ENABLED virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override; #endif diff --git a/tests/core/io/test_marshalls.h b/tests/core/io/test_marshalls.h index de8d6e1406..6716984681 100644 --- a/tests/core/io/test_marshalls.h +++ b/tests/core/io/test_marshalls.h @@ -160,7 +160,7 @@ TEST_CASE("[Marshalls] NIL Variant encoding") { uint8_t buffer[4]; CHECK(encode_variant(variant, buffer, r_len) == OK); - CHECK_MESSAGE(r_len == 4, "Length == 4 bytes for header"); + CHECK_MESSAGE(r_len == 4, "Length == 4 bytes for header."); CHECK_MESSAGE(buffer[0] == 0x00, "Variant::NIL"); CHECK(buffer[1] == 0x00); CHECK(buffer[2] == 0x00); @@ -174,7 +174,7 @@ TEST_CASE("[Marshalls] INT 32 bit Variant encoding") { uint8_t buffer[8]; CHECK(encode_variant(variant, buffer, r_len) == OK); - CHECK_MESSAGE(r_len == 8, "Length == 4 bytes for header + 4 bytes for int32_t"); + CHECK_MESSAGE(r_len == 8, "Length == 4 bytes for header + 4 bytes for `int32_t`."); CHECK_MESSAGE(buffer[0] == 0x02, "Variant::INT"); CHECK(buffer[1] == 0x00); CHECK(buffer[2] == 0x00); @@ -192,7 +192,7 @@ TEST_CASE("[Marshalls] INT 64 bit Variant encoding") { uint8_t buffer[12]; CHECK(encode_variant(variant, buffer, r_len) == OK); - CHECK_MESSAGE(r_len == 12, "Length == 4 bytes for header + 8 bytes for int64_t"); + CHECK_MESSAGE(r_len == 12, "Length == 4 bytes for header + 8 bytes for `int64_t`."); CHECK_MESSAGE(buffer[0] == 0x02, "Variant::INT"); CHECK(buffer[1] == 0x00); CHECK_MESSAGE(buffer[2] == 0x01, "HEADER_DATA_FLAG_64"); @@ -214,7 +214,7 @@ TEST_CASE("[Marshalls] FLOAT single precision Variant encoding") { uint8_t buffer[8]; CHECK(encode_variant(variant, buffer, r_len) == OK); - CHECK_MESSAGE(r_len == 8, "Length == 4 bytes for header + 4 bytes for float"); + CHECK_MESSAGE(r_len == 8, "Length == 4 bytes for header + 4 bytes for `float`."); CHECK_MESSAGE(buffer[0] == 0x03, "Variant::FLOAT"); CHECK(buffer[1] == 0x00); CHECK(buffer[2] == 0x00); @@ -232,7 +232,7 @@ TEST_CASE("[Marshalls] FLOAT double precision Variant encoding") { uint8_t buffer[12]; CHECK(encode_variant(variant, buffer, r_len) == OK); - CHECK_MESSAGE(r_len == 12, "Length == 4 bytes for header + 8 bytes for double"); + CHECK_MESSAGE(r_len == 12, "Length == 4 bytes for header + 8 bytes for `double`."); CHECK_MESSAGE(buffer[0] == 0x03, "Variant::FLOAT"); CHECK(buffer[1] == 0x00); CHECK_MESSAGE(buffer[2] == 0x01, "HEADER_DATA_FLAG_64"); @@ -335,10 +335,10 @@ TEST_CASE("[Marshalls] Typed array encoding") { uint8_t buffer[24]; CHECK(encode_variant(array, buffer, r_len) == OK); - CHECK_MESSAGE(r_len == 24, "Length == 4 bytes for header + 4 bytes for array type + 4 bytes for array size + 12 bytes for element"); + CHECK_MESSAGE(r_len == 24, "Length == 4 bytes for header + 4 bytes for array type + 4 bytes for array size + 12 bytes for element."); CHECK_MESSAGE(buffer[0] == 0x1c, "Variant::ARRAY"); CHECK(buffer[1] == 0x00); - CHECK_MESSAGE(buffer[2] == 0x01, "HEADER_DATA_FIELD_TYPED_ARRAY_BUILTIN"); + CHECK_MESSAGE(buffer[2] == 0x01, "CONTAINER_TYPE_KIND_BUILTIN"); CHECK(buffer[3] == 0x00); // Check array type. CHECK_MESSAGE(buffer[4] == 0x02, "Variant::INT"); @@ -370,7 +370,7 @@ TEST_CASE("[Marshalls] Typed array decoding") { Variant variant; int r_len; uint8_t buffer[] = { - 0x1c, 0x00, 0x01, 0x00, // Variant::ARRAY, HEADER_DATA_FIELD_TYPED_ARRAY_BUILTIN + 0x1c, 0x00, 0x01, 0x00, // Variant::ARRAY, CONTAINER_TYPE_KIND_BUILTIN 0x02, 0x00, 0x00, 0x00, // Array type (Variant::INT). 0x01, 0x00, 0x00, 0x00, // Array size. 0x02, 0x00, 0x01, 0x00, // Element type (Variant::INT, HEADER_DATA_FLAG_64). @@ -386,6 +386,89 @@ TEST_CASE("[Marshalls] Typed array decoding") { CHECK(array[0] == Variant(uint64_t(0x0f123456789abcdef))); } +TEST_CASE("[Marshalls] Typed dicttionary encoding") { + int r_len; + Dictionary dictionary; + dictionary.set_typed(Variant::INT, StringName(), Ref<Script>(), Variant::INT, StringName(), Ref<Script>()); + dictionary[Variant(uint64_t(0x0f123456789abcdef))] = Variant(uint64_t(0x0f123456789abcdef)); + uint8_t buffer[40]; + + CHECK(encode_variant(dictionary, buffer, r_len) == OK); + CHECK_MESSAGE(r_len == 40, "Length == 4 bytes for header + 8 bytes for dictionary type + 4 bytes for dictionary size + 24 bytes for key-value pair."); + CHECK_MESSAGE(buffer[0] == 0x1b, "Variant::DICTIONARY"); + CHECK(buffer[1] == 0x00); + CHECK_MESSAGE(buffer[2] == 0x05, "key: CONTAINER_TYPE_KIND_BUILTIN | value: CONTAINER_TYPE_KIND_BUILTIN"); + CHECK(buffer[3] == 0x00); + // Check dictionary key type. + CHECK_MESSAGE(buffer[4] == 0x02, "Variant::INT"); + CHECK(buffer[5] == 0x00); + CHECK(buffer[6] == 0x00); + CHECK(buffer[7] == 0x00); + // Check dictionary value type. + CHECK_MESSAGE(buffer[8] == 0x02, "Variant::INT"); + CHECK(buffer[9] == 0x00); + CHECK(buffer[10] == 0x00); + CHECK(buffer[11] == 0x00); + // Check dictionary size. + CHECK(buffer[12] == 0x01); + CHECK(buffer[13] == 0x00); + CHECK(buffer[14] == 0x00); + CHECK(buffer[15] == 0x00); + // Check key type. + CHECK_MESSAGE(buffer[16] == 0x02, "Variant::INT"); + CHECK(buffer[17] == 0x00); + CHECK_MESSAGE(buffer[18] == 0x01, "HEADER_DATA_FLAG_64"); + CHECK(buffer[19] == 0x00); + // Check key value. + CHECK(buffer[20] == 0xef); + CHECK(buffer[21] == 0xcd); + CHECK(buffer[22] == 0xab); + CHECK(buffer[23] == 0x89); + CHECK(buffer[24] == 0x67); + CHECK(buffer[25] == 0x45); + CHECK(buffer[26] == 0x23); + CHECK(buffer[27] == 0xf1); + // Check value type. + CHECK_MESSAGE(buffer[28] == 0x02, "Variant::INT"); + CHECK(buffer[29] == 0x00); + CHECK_MESSAGE(buffer[30] == 0x01, "HEADER_DATA_FLAG_64"); + CHECK(buffer[31] == 0x00); + // Check value value. + CHECK(buffer[32] == 0xef); + CHECK(buffer[33] == 0xcd); + CHECK(buffer[34] == 0xab); + CHECK(buffer[35] == 0x89); + CHECK(buffer[36] == 0x67); + CHECK(buffer[37] == 0x45); + CHECK(buffer[38] == 0x23); + CHECK(buffer[39] == 0xf1); +} + +TEST_CASE("[Marshalls] Typed dictionary decoding") { + Variant variant; + int r_len; + uint8_t buffer[] = { + 0x1b, 0x00, 0x05, 0x00, // Variant::DICTIONARY, key: CONTAINER_TYPE_KIND_BUILTIN | value: CONTAINER_TYPE_KIND_BUILTIN + 0x02, 0x00, 0x00, 0x00, // Dictionary key type (Variant::INT). + 0x02, 0x00, 0x00, 0x00, // Dictionary value type (Variant::INT). + 0x01, 0x00, 0x00, 0x00, // Dictionary size. + 0x02, 0x00, 0x01, 0x00, // Key type (Variant::INT, HEADER_DATA_FLAG_64). + 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0xf1, // Key value. + 0x02, 0x00, 0x01, 0x00, // Value type (Variant::INT, HEADER_DATA_FLAG_64). + 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0xf1, // Value value. + }; + + CHECK(decode_variant(variant, buffer, 40, &r_len) == OK); + CHECK(r_len == 40); + CHECK(variant.get_type() == Variant::DICTIONARY); + Dictionary dictionary = variant; + CHECK(dictionary.get_typed_key_builtin() == Variant::INT); + CHECK(dictionary.get_typed_value_builtin() == Variant::INT); + CHECK(dictionary.size() == 1); + CHECK(dictionary.has(Variant(uint64_t(0x0f123456789abcdef)))); + CHECK(dictionary[Variant(uint64_t(0x0f123456789abcdef))] == Variant(uint64_t(0x0f123456789abcdef))); +} + } // namespace TestMarshalls #endif // TEST_MARSHALLS_H diff --git a/tests/core/string/test_translation.h b/tests/core/string/test_translation.h index 7c389191e3..2b1069d40c 100644 --- a/tests/core/string/test_translation.h +++ b/tests/core/string/test_translation.h @@ -161,7 +161,7 @@ TEST_CASE("[TranslationCSV] CSV import") { List<String> gen_files; - Error result = import_csv_translation->import(TestUtils::get_data_path("translations.csv"), + Error result = import_csv_translation->import(0, TestUtils::get_data_path("translations.csv"), "", options, nullptr, &gen_files); CHECK(result == OK); CHECK(gen_files.size() == 4); diff --git a/tests/core/string/test_translation_server.h b/tests/core/string/test_translation_server.h index ac1599f2e8..6668a7b57b 100644 --- a/tests/core/string/test_translation_server.h +++ b/tests/core/string/test_translation_server.h @@ -37,27 +37,37 @@ namespace TestTranslationServer { TEST_CASE("[TranslationServer] Translation operations") { - Ref<Translation> t = memnew(Translation); - t->set_locale("uk"); - t->add_message("Good Morning", String::utf8("Добрий ранок")); + Ref<Translation> t1 = memnew(Translation); + t1->set_locale("uk"); + t1->add_message("Good Morning", String(U"Добрий ранок")); + + Ref<Translation> t2 = memnew(Translation); + t2->set_locale("uk"); + t2->add_message("Hello Godot", String(U"你好戈多")); TranslationServer *ts = TranslationServer::get_singleton(); + // Adds translation for UK locale for the first time. int l_count_before = ts->get_loaded_locales().size(); - ts->add_translation(t); + ts->add_translation(t1); int l_count_after = ts->get_loaded_locales().size(); - // Newly created Translation object should be added to the list, so the counter should increase, too. CHECK(l_count_after > l_count_before); - Ref<Translation> trans = ts->get_translation_object("uk"); - CHECK(trans.is_valid()); + // Adds translation for UK locale again. + ts->add_translation(t2); + CHECK_EQ(ts->get_loaded_locales().size(), l_count_after); + + // Removing that translation. + ts->remove_translation(t2); + CHECK_EQ(ts->get_loaded_locales().size(), l_count_after); + + CHECK(ts->get_translation_object("uk").is_valid()); ts->set_locale("uk"); CHECK(ts->translate("Good Morning") == String::utf8("Добрий ранок")); - ts->remove_translation(t); - trans = ts->get_translation_object("uk"); - CHECK(trans.is_null()); + ts->remove_translation(t1); + CHECK(ts->get_translation_object("uk").is_null()); // If no suitable Translation object has been found - the original message should be returned. CHECK(ts->translate("Good Morning") == "Good Morning"); } @@ -110,18 +120,50 @@ TEST_CASE("[TranslationServer] Comparing locales") { locale_a = "sr-Latn-CS"; locale_b = "sr-Latn-RS"; - // Two elements from locales match. + // Script matches (+1) but country doesn't (-1). res = ts->compare_locales(locale_a, locale_b); - CHECK(res == 2); + CHECK(res == 5); locale_a = "uz-Cyrl-UZ"; locale_b = "uz-Latn-UZ"; - // Two elements match, but they are not sequentual. + // Country matches (+1) but script doesn't (-1). + res = ts->compare_locales(locale_a, locale_b); + + CHECK(res == 5); + + locale_a = "aa-Latn-ER"; + locale_b = "aa-Latn-ER-saaho"; + + // Script and country match (+2) with variant on one locale (+0). res = ts->compare_locales(locale_a, locale_b); - CHECK(res == 2); + CHECK(res == 7); + + locale_a = "uz-Cyrl-UZ"; + locale_b = "uz-Latn-KG"; + + // Both script and country mismatched (-2). + res = ts->compare_locales(locale_a, locale_b); + + CHECK(res == 3); + + locale_a = "es-ES"; + locale_b = "es-AR"; + + // Mismatched country (-1). + res = ts->compare_locales(locale_a, locale_b); + + CHECK(res == 4); + + locale_a = "es"; + locale_b = "es-AR"; + + // No country for one locale (+0). + res = ts->compare_locales(locale_a, locale_b); + + CHECK(res == 5); locale_a = "es-EC"; locale_b = "fr-LU"; @@ -130,6 +172,24 @@ TEST_CASE("[TranslationServer] Comparing locales") { res = ts->compare_locales(locale_a, locale_b); CHECK(res == 0); + + locale_a = "zh-HK"; + locale_b = "zh"; + + // In full standardization, zh-HK becomes zh_Hant_HK and zh becomes + // zh_Hans_CN. Both script and country mismatch (-2). + res = ts->compare_locales(locale_a, locale_b); + + CHECK(res == 3); + + locale_a = "zh-CN"; + locale_b = "zh"; + + // In full standardization, zh and zh-CN both become zh_Hans_CN for an + // exact match. + res = ts->compare_locales(locale_a, locale_b); + + CHECK(res == 10); } } // namespace TestTranslationServer diff --git a/tests/core/variant/test_callable.h b/tests/core/variant/test_callable.h index 3228e0a583..34ea8fad5c 100644 --- a/tests/core/variant/test_callable.h +++ b/tests/core/variant/test_callable.h @@ -135,6 +135,70 @@ TEST_CASE("[Callable] Argument count") { memdelete(my_test); } + +class TestBoundUnboundArgumentCount : public Object { + GDCLASS(TestBoundUnboundArgumentCount, Object); + +protected: + static void _bind_methods() { + ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "test_func", &TestBoundUnboundArgumentCount::test_func, MethodInfo("test_func")); + } + +public: + Variant test_func(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { + Array result; + result.resize(p_argcount); + for (int i = 0; i < p_argcount; i++) { + result[i] = *p_args[i]; + } + return result; + } + + static String get_output(const Callable &p_callable) { + Array effective_args; + effective_args.push_back(7); + effective_args.push_back(8); + effective_args.push_back(9); + + effective_args.resize(3 - p_callable.get_unbound_arguments_count()); + effective_args.append_array(p_callable.get_bound_arguments()); + + return vformat( + "%d %d %s %s %s", + p_callable.get_unbound_arguments_count(), + p_callable.get_bound_arguments_count(), + p_callable.get_bound_arguments(), + p_callable.call(7, 8, 9), + effective_args); + } +}; + +TEST_CASE("[Callable] Bound and unbound argument count") { + String (*get_output)(const Callable &) = TestBoundUnboundArgumentCount::get_output; + + TestBoundUnboundArgumentCount *test_instance = memnew(TestBoundUnboundArgumentCount); + + Callable test_func = Callable(test_instance, "test_func"); + + CHECK(get_output(test_func) == "0 0 [] [7, 8, 9] [7, 8, 9]"); + CHECK(get_output(test_func.bind(1, 2)) == "0 2 [1, 2] [7, 8, 9, 1, 2] [7, 8, 9, 1, 2]"); + CHECK(get_output(test_func.bind(1, 2).unbind(1)) == "1 2 [1, 2] [7, 8, 1, 2] [7, 8, 1, 2]"); + CHECK(get_output(test_func.bind(1, 2).unbind(1).bind(3, 4)) == "0 3 [3, 1, 2] [7, 8, 9, 3, 1, 2] [7, 8, 9, 3, 1, 2]"); + CHECK(get_output(test_func.bind(1, 2).unbind(1).bind(3, 4).unbind(1)) == "1 3 [3, 1, 2] [7, 8, 3, 1, 2] [7, 8, 3, 1, 2]"); + + CHECK(get_output(test_func.bind(1).bind(2).bind(3).unbind(1)) == "1 3 [3, 2, 1] [7, 8, 3, 2, 1] [7, 8, 3, 2, 1]"); + CHECK(get_output(test_func.bind(1).bind(2).unbind(1).bind(3)) == "0 2 [2, 1] [7, 8, 9, 2, 1] [7, 8, 9, 2, 1]"); + CHECK(get_output(test_func.bind(1).unbind(1).bind(2).bind(3)) == "0 2 [3, 1] [7, 8, 9, 3, 1] [7, 8, 9, 3, 1]"); + CHECK(get_output(test_func.unbind(1).bind(1).bind(2).bind(3)) == "0 2 [3, 2] [7, 8, 9, 3, 2] [7, 8, 9, 3, 2]"); + + CHECK(get_output(test_func.unbind(1).unbind(1).unbind(1).bind(1, 2, 3)) == "0 0 [] [7, 8, 9] [7, 8, 9]"); + CHECK(get_output(test_func.unbind(1).unbind(1).bind(1, 2, 3).unbind(1)) == "1 1 [1] [7, 8, 1] [7, 8, 1]"); + CHECK(get_output(test_func.unbind(1).bind(1, 2, 3).unbind(1).unbind(1)) == "2 2 [1, 2] [7, 1, 2] [7, 1, 2]"); + CHECK(get_output(test_func.bind(1, 2, 3).unbind(1).unbind(1).unbind(1)) == "3 3 [1, 2, 3] [1, 2, 3] [1, 2, 3]"); + + memdelete(test_instance); +} + } // namespace TestCallable #endif // TEST_CALLABLE_H diff --git a/tests/scene/test_audio_stream_wav.h b/tests/scene/test_audio_stream_wav.h index d3d5cc8a30..7276dd0878 100644 --- a/tests/scene/test_audio_stream_wav.h +++ b/tests/scene/test_audio_stream_wav.h @@ -162,7 +162,7 @@ void run_test(String file_name, AudioStreamWAV::Format data_format, bool stereo, // Compressed streams can't be saved, disable compression. options_map["compress/mode"] = 0; - REQUIRE(wav_importer->import(save_path, save_path, options_map, nullptr) == OK); + REQUIRE(wav_importer->import(0, save_path, save_path, options_map, nullptr) == OK); String load_path = save_path + "." + wav_importer->get_save_extension(); Ref<AudioStreamWAV> loaded_stream = ResourceLoader::load(load_path, "AudioStreamWAV", ResourceFormatImporter::CACHE_MODE_IGNORE, &error); diff --git a/tests/scene/test_viewport.h b/tests/scene/test_viewport.h index dde37944ec..06a38f234b 100644 --- a/tests/scene/test_viewport.h +++ b/tests/scene/test_viewport.h @@ -1577,7 +1577,7 @@ TEST_CASE("[SceneTree][Viewport] Physics Picking 2D") { PickingCollider pc; pc.a = memnew(TestArea2D); pc.c = memnew(CollisionShape2D); - pc.r = Ref<RectangleShape2D>(memnew(RectangleShape2D)); + pc.r.instantiate(); pc.r->set_size(Size2(150, 150)); pc.c->set_shape(pc.r); pc.a->add_child(pc.c); |